A browser library that provides a console command system.
Register custom commands and execute them via the browser console (DevTools) with a $ prefix or via the dropdown or embedded terminal Custom Element (Web Component).
This can be very useful for web apps that need to provide a console for users to interact with the app, bypassing the UI for power users.
- 🚀 Zero dependencies (runtime)
- 📦 Built with esbuild for fast builds
- 🔧 TypeScript for type safety
- 🎯 Flexible command parsing (positional args + key=value pairs)
- 📝 Built-in commands:
$help,$about - 🔌 Extensible command system
pnpm add @mathiscode/pucc
# or
yarn add @mathiscode/pucc
# or
npm install @mathiscode/pucc<script src="https://unpkg.com/@mathiscode/pucc/dist/pucc.js"></script>After including the library, commands are automatically available in the browser console:
// Built-in commands
$help() // Lists all available commands
$about() // Shows library information// Register a new command
Pucc.addCommand('new', (args) => {
console.log('Creating:', args._[0]);
console.log('Arguments:', args);
}, 'Create a new entity');
// Now you can use it in the console or dropdown terminal:
// $new('customer', 'name="John Smith"', 'balance=5400')
// new customer name="John Smith" balance=5400The command parser supports flexible argument formats:
Positional arguments:
$new customer
// args = { _: ['customer'] }Key-value pairs:
$new name="John Smith" balance=5400
// args = { name: "John Smith", balance: 5400 }Mixed (positional + key-value):
$new customer name="John Smith" balance=5400
// args = { _: ['customer'], name: "John Smith", balance: 5400 }Type conversion:
- Numbers are automatically parsed:
balance=5400→5400(number) - Booleans:
active=true→true(boolean) - Strings:
name="John"→"John"(string)
When using ESM, no global instance is created automatically. You have full control over how Pucc instances are created and used:
import { Pucc } from 'pucc';
// Create a Pucc instance
// Commands are automatically registered on window (for console access)
const shell = new Pucc();
// Add commands - they're immediately available in console AND terminals
shell.addCommand('greet', (args) => {
console.log(`Hello, ${args._[0] || 'World'}!`);
}, 'Greet someone');
// Commands are now available:
// - In browser console: $greet('Alice') or greet('Alice')
// - In terminal elements: greet AliceBy default, enableGlobalRegistrations: true registers commands on the window object, making them accessible from the browser console. This does NOT affect terminal access - terminals can use any Pucc instance regardless of this setting.
import { Pucc } from 'pucc';
// Option 1: Commands available in console AND terminals (default)
const shell = new Pucc();
shell.addCommand('test', () => console.log('test'), 'Test command');
// Available as: $test() in console, or "test" in terminals
// Option 2: Commands available ONLY in terminals (not in console)
const shell = new Pucc({ enableGlobalRegistrations: false });
shell.addCommand('test', () => console.log('test'), 'Test command');
// Available as: "test" in terminals only (not on window)Key Points:
enableGlobalRegistrationsonly controls whether commands appear onwindow(for console access)- Terminals can use ANY Pucc instance, regardless of this setting
- Set to
falseif you want to avoid polluting the global namespace
By default, commands use the $ prefix (e.g., $help, $about). You can customize this prefix when creating a Pucc instance:
import { Pucc } from 'pucc';
// Use a custom prefix (must be a valid JavaScript identifier)
const shell = new Pucc({ commandPrefix: 'cmd' });
// Now commands can be called with the custom prefix
// cmdhelp() or cmdabout() in the console
// Or without prefix: help() or about()
// Commands are still accessible both ways
shell.addCommand('greet', (args) => {
console.log(`Hello, ${args._[0] || 'World'}!`);
}, 'Greet someone');
// Can be called as: cmdgreet('Alice')Valid prefix examples:
$(default)_cmdmyPrefixprefix123_prefix
Invalid prefix examples:
>(special character not allowed)123(cannot start with a digit)prefix-(hyphen not allowed)prefix.(dot not allowed)
Note: The prefix must be a valid JavaScript identifier (starts with a letter, underscore, or dollar sign; can only contain letters, digits, underscores, and dollar signs). The prefix is used for console commands and is automatically stripped when parsing command input. Commands can always be called with or without the prefix in the terminal.
The <pucc-terminal> custom element can use either:
- A shared global instance (
window.Pucc) - created automatically in IIFE builds - Its own isolated instance - configured via
puccOptions
Configuring a Terminal with Its Own Instance:
Via attribute (for simple options):
<pucc-terminal
embedded="true"
height="300px"
theme="dark"
prompt="# "
hotkey="alt+s"
initial-content="Welcome to my terminal!"
pucc-options='{"enableGlobalRegistrations": false, "commandPrefix": "_"}'>
</pucc-terminal>Terminal Attributes:
embedded- Set to"true"for embedded mode (always visible)height- Terminal height (e.g.,"300px","50vh")theme- Color theme ("dark"or"light")prompt- Custom prompt text (default:"$ ")hotkey- Keyboard shortcut for dropdown terminals (e.g.,"alt+s","ctrl+shift+t")initial-content- Custom initial content to display instead of the default welcome message (supports newlines with\n)pucc-options- JSON string with Pucc constructor options (see below)
Via property (for full functionality, including functions):
import { Pucc } from 'pucc';
const terminal = document.querySelector('pucc-terminal');
terminal.puccOptions = {
enableGlobalRegistrations: false,
commandPrefix: 'cmd',
customHelpHandler: (args, shell) => {
console.log('Custom help!');
},
initialCommands: [
{
name: 'greet',
description: 'Greet someone',
handler: (args) => {
console.log(`Hello, ${args._[0] || 'World'}!`);
}
}
]
};Adding Commands to a Terminal Element:
If a terminal uses its own instance (via puccOptions), you can add commands to it:
const terminal = document.querySelector('pucc-terminal');
// Get the terminal's Pucc instance
const shell = terminal.shellInstance;
if (shell) {
// Add commands directly to the terminal's instance
shell.addCommand('mycommand', (args) => {
console.log('Command executed in terminal');
}, 'My custom command');
}Using the Global Instance:
If a terminal doesn't have puccOptions set, it automatically uses window.Pucc (if available). In this case, commands added to the global instance are available in all terminals:
// In IIFE builds, window.Pucc is created automatically
// In ESM builds, create it yourself:
window.Pucc = new Pucc();
// Add commands - they're available in all terminals using the global instance
shell.addCommand('shared', () => console.log('Shared command'), 'Shared command');Note: The pucc-options attribute only supports JSON-serializable options (enableGlobalRegistrations, commandPrefix). For options that include functions (customHelpHandler, initialCommands), use the puccOptions property instead.
The terminal component supports CSS custom properties for advanced styling:
pucc-terminal {
--shell-bg: #1a1a1a;
--shell-fg: #e0e0e0;
--shell-accent: #00aaff;
--shell-border: rgba(255, 255, 255, 0.1);
--shell-font-family: 'Courier New', monospace;
--shell-font-size: 16px;
--shell-padding: 20px;
--shell-animation-duration: 0.3s;
--shell-border-radius: 12px;
--shell-shadow: 0 12px 48px rgba(0, 0, 0, 0.5);
--shell-backdrop-blur: 15px;
}Available CSS Variables:
--shell-bg- Background color--shell-fg- Foreground/text color--shell-accent- Accent color (cursor, selection)--shell-border- Border color--shell-font-family- Font family--shell-font-size- Font size--shell-padding- Padding--shell-animation-duration- Animation duration--shell-border-radius- Border radius--shell-shadow- Box shadow--shell-backdrop-blur- Backdrop blur amount (dropdown terminals only)
Create a new Pucc instance.
Parameters:
options(object, optional): Configuration optionscustomHelpHandler(function, optional): Custom handler for thehelpcommandinitialCommands(Command[], optional): Array of commands to register on initializationenableGlobalRegistrations(boolean, optional): Whether to register commands globally onwindowfor console access. Defaults totrue. Set tofalseto avoid polluting the global namespace. Note: This only affects console access, not terminal access - terminals can use any instance regardless of this setting.commandPrefix(string, optional): Custom prefix for console commands. Defaults to$. Must be a valid JavaScript identifier (starts with letter, underscore, or dollar sign; can contain letters, digits, underscores, and dollar signs). Commands can be called with or without the prefix in terminals.
Example:
// Default behavior (global registrations enabled, $ prefix)
const shell = new Pucc();
// Commands immediately available in console and terminals
// Disable global registrations (console access only, terminals still work)
const shell = new Pucc({ enableGlobalRegistrations: false });
// Commands available in terminals, NOT in console
// Use custom command prefix
const shell = new Pucc({ commandPrefix: 'cmd_' });
// Console: cmd_help(), Terminal: help or cmd_helpRegister a new command on a Pucc instance. The command is immediately available in terminals and (if enableGlobalRegistrations is true) in the console.
Parameters:
name(string): Command name (without prefix)handler(function): Command handler function(args: ParsedArgs, shell?: Pucc) => void | Promise<void>description(string): Command description (shown inhelp)
Example:
const shell = new Pucc();
// Add a command - immediately available
shell.addCommand('greet', (args) => {
const name = args.name || args._[0] || 'World';
console.log(`Hello, ${name}!`);
}, 'Greet someone by name');
// In console: $greet('Alice') or greet('Alice')
// In terminal: greet Alice or greet name=AliceNote: In IIFE builds, you can also use Pucc.addCommand() which adds to the global instance automatically created.
Remove a command from a Pucc instance. The command is immediately removed from terminals and (if enableGlobalRegistrations is true) from the console.
Parameters:
name(string): Command name (without prefix)
Returns:
boolean:trueif the command was successfully removed,falseif the command was not found
Example:
const shell = new Pucc();
// Add a command
shell.addCommand('greet', (args) => {
console.log(`Hello, ${args._[0] || 'World'}!`);
}, 'Greet someone');
// Remove the command
const removed = shell.removeCommand('greet');
if (removed) {
console.log('Command removed successfully');
} else {
console.log('Command not found');
}
// The command is no longer available in console or terminalsNote: In IIFE builds, you can also use Pucc.removeCommand() which removes from the global instance automatically created.
The argument object passed to command handlers:
interface ParsedArgs {
_: string[]; // Positional arguments
[key: string]: string | number | boolean | string[];
}# Install dependencies
pnpm install
# Build for production
pnpm build
# Build in watch mode (development)
pnpm build:dev
# Run linter
pnpm lint
# Format code
pnpm format
# Run server
pnpm server
# Type check
pnpm type-checkpucc/
├── src/
│ ├── index.ts # Main entry point
│ ├── core/
│ │ ├── Pucc.ts # Core class
│ │ └── CommandParser.ts # Command parser
│ ├── commands/
│ │ ├── help.ts # $help command
│ │ ├── about.ts # $about command
│ │ └── echo.ts # $echo command
│ ├── components/
│ │ ├── ShellTerminal.ts # Terminal custom element
│ │ └── TerminalLogger.ts # Terminal logger component
│ ├── types.ts # Type definitions
│ └── demo.css # Demo styles
├── config/
│ └── build.js # Build configuration
├── public/ # Demo and development files
├── dist/ # Build output
├── eslint.config.mts # ESLint configuration
├── tsconfig.json # TypeScript configuration
└── server.js # Development server
Pucc is created and maintained by Jay Mathis, a developer passionate about building useful tools for the web.
Connect and explore:
- GitHub Profile - Check out my other projects and contributions
- Website - Learn more about me and my work