Add a safe, fake terminal to any normal website. Visitors type commands like about, features, or contact; your site prints the answers you define.
Live builder · CDN example · Minimal example · Recipes · Launch notes · MIT license
If this saves you time, star the repo so other people can find it.
- Vanilla HTML, CSS, and JavaScript
- No build step
- No dependencies
- Browser-only: it never runs real shell commands
- Built-in
helpandclear - ArrowUp and ArrowDown command history
- Ctrl+L keyboard clear
- Escape clears the current input
- Labeled input for screen readers
- Scoped CSS for safer copy-paste embeds
- Command arguments for callback commands
- Safe fallback if a custom command throws
- Deduplicated built-in command names in
help - Forgiving
welcomeconfig for common copy-paste mistakes - Builder UI that generates the embed code for you
Open the live builder, add your commands and answers, then copy the generated embed code.
| If you want to... | Use this |
|---|---|
| Add a terminal to a live site quickly | Live builder |
| Paste one snippet into a custom HTML block | CDN mode |
| Keep all assets in your own repo | Local files mode |
| Fork the whole starter and customize it | Use this template |
Want the smallest possible page? Open examples/minimal.html. Want a no-download embed? Open examples/cdn.html.
The builder can generate CDN links that work anywhere, or local paths when you want to copy terminal.css and terminal.js into your project.
Using Astro, Vite, React, Next.js, WordPress, Webflow, or a strict CSP? See RECIPES.md.
Paste this anywhere:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/MIR4ZZZ/website-terminal@v1.0.16/terminal.css" />
<div id="site-terminal"></div>
<script src="https://cdn.jsdelivr.net/gh/MIR4ZZZ/website-terminal@v1.0.16/terminal.js"></script>
<script>
WebsiteTerminal.mount('#site-terminal', {
title: 'guest@your-site: ~',
welcome: ['Website terminal loaded.', 'Type "help" for commands.'],
commands: {
about: {
description: 'what this site is',
text: 'Replace this with your about text.',
},
contact: {
description: 'how to reach you',
text: 'Replace this with your contact link or email.',
},
},
});
</script>Or copy these two files beside your page:
terminal.cssterminal.js
Add a mount point:
<link rel="stylesheet" href="./terminal.css" />
<div id="site-terminal"></div>
<script src="./terminal.js"></script>
<script>
WebsiteTerminal.mount('#site-terminal', {
title: 'guest@your-site: ~',
welcome: ['Website terminal loaded.', 'Type "help" for commands.'],
commands: {
about: {
description: 'what this site is',
text: 'Replace this with your about text.',
},
contact: {
description: 'how to reach you',
text: 'Replace this with your contact link or email.',
},
},
});
</script>help and clear are built in. Add your own commands in the commands object:
WebsiteTerminal.mount('#site-terminal', {
commands: {
docs: {
description: 'read the docs',
text: 'https://example.com/docs',
},
time: {
description: 'browser time',
run: () => new Date().toLocaleString(),
},
},
});Command output is rendered with textContent, not innerHTML, so visitor input cannot inject HTML.
Mount the widget with WebsiteTerminal.mount(target, options).
| Option | Type | Default |
|---|---|---|
target |
CSS selector or DOM element | Required |
title |
string | guest@website: ~ |
prompt |
string | $ |
placeholder |
string | Type "help" and press Enter... |
welcome |
string or string[] | ['Website terminal loaded.', 'Type "help" for commands.'] |
commands |
object | {} |
Command names are matched case-insensitively. If the full typed line is not a command, the first word is matched as the command and the full line is passed to callbacks. help and clear stay reserved for the built-in help list and screen clear action.
Each command can be a plain string, a function, or an object:
commands: {
about: 'A short static answer.',
time: () => new Date().toLocaleString(),
docs: {
description: 'read the docs',
text: 'https://example.com/docs',
},
echo: {
description: 'repeat the raw command',
run: (rawCommand) => `You typed: ${rawCommand}`,
},
}Callback return values and object text values are converted to text before rendering.
Change the terminal colors with CSS variables:
.website-terminal {
--wt-bg: rgba(6, 8, 10, 0.95);
--wt-border: rgba(255, 255, 255, 0.12);
--wt-panel: rgba(255, 255, 255, 0.055);
--wt-text: #f5f7fa;
--wt-muted: #aeb7b2;
--wt-accent: #8fe6bf;
--wt-prompt: #f6c177;
}npm testThe tests check syntax, command behavior, and the builder embed generator. There is no package install step.
This is a fake terminal. It only matches commands from your allowlist and prints text in the browser. Do not wire raw visitor input to a real shell.
MIT
