Example extensions
Two complete walkthroughs, built from the schema's sample files. The first is a theme + command extension that touches every contribution type; the second is a minimal code-free extension.
Example 1 — Dracula Warm (theme + command)
This is the canonical sample (schemas/example.aero.json + schemas/example-theme.json). It contributes a theme, a command to apply it, a keybinding, and a JavaScript snippet — and wires the command with sandboxed JS.
Folder layout
dracula-warm/
├── aero.json
├── extension.js
├── themes/
│ └── dracula-warm.json
└── snippets/
└── javascript.jsonaero.json
{
"name": "dracula-warm",
"displayName": "Dracula Warm",
"publisher": "aero",
"version": "1.0.0",
"description": "A cozy, warm take on Dracula for Aero — plus a command to apply it.",
"tagline": "Cozy warm dark colors",
"category": "Themes",
"icon": "🧛",
"tags": ["dark", "warm", "theme"],
"engines": { "aero": ">=0.5.0" },
"main": "extension.js",
"activationEvents": ["onCommand:dracula-warm.apply"],
"contributes": {
"themes": [
{ "label": "Dracula Warm", "uiTheme": "dark", "path": "themes/dracula-warm.json" }
],
"commands": [
{ "command": "dracula-warm.apply", "title": "Dracula Warm: Apply Theme" }
],
"keybindings": [
{ "key": "cmd+k cmd+d", "command": "dracula-warm.apply", "when": "always" }
],
"snippets": [
{ "language": "javascript", "path": "snippets/javascript.json" }
]
}
}What each piece does:
themes[]registers a dark theme labelled Dracula Warm, loaded fromthemes/dracula-warm.json.commands[]adds Dracula Warm: Apply Theme to the palette.keybindings[]bindscmd+k cmd+dto that command, everywhere (always).snippets[]registers JavaScript snippets.main+activationEventsloadextension.jslazily when the command runs.
themes/dracula-warm.json
{
"name": "Dracula Warm",
"type": "dark",
"monaco": "vs-dark",
"tokens": {
"bg": "#211f26",
"raised": "#282a36",
"panel": "#2f3140",
"text": "#f8f8f2",
"subtext": "#b9b6c8",
"border": "#3b3d4d",
"accent": "#ff9e64",
"accent-hover": "#e8853f"
}
}A dark base extended by eight token overrides; every unset token inherits from Aero's built-in dark theme. See Themes for the full token set.
extension.js
'use strict';
// Sandboxed: only `aero.*` is available — no DOM, Node, or window.api.
function activate(context) {
const sub = aero.commands.registerCommand('dracula-warm.apply', async () => {
await aero.theme.apply('Dracula Warm'); // switch by contributed label
aero.window.setStatusBarMessage('Dracula Warm applied', 2000);
});
context.subscriptions.push(sub); // host disposes on deactivate
}
function deactivate() {}The handler uses aero.theme.apply and aero.window.setStatusBarMessage. Because the theme also registers declaratively, users can switch to it without ever running the command — the command (and its keybinding) are just a fast path.
snippets/javascript.json
{
"Log to console": {
"prefix": "log",
"body": ["console.log('$1', $1);", "$0"],
"description": "Console log a value"
}
}Build, sideload, try
npx aero-ext package # → aero.dracula-warm-1.0.0.aero-ext
# In Aero: Extensions view → Install from file… → pick the .aero-extThen: run Dracula Warm: Apply Theme from the palette (or press cmd+k cmd+d), and type log in a JS file to see the snippet.
Example 2 — a code-free theme
The smallest possible extension: a theme with no command, no main, and no activation events. Three of the four contribution types are like this — pure JSON, applied by trusted core.
Folder layout
paper-light/
├── aero.json
└── themes/
└── paper-light.jsonaero.json
{
"name": "paper-light",
"displayName": "Paper Light",
"publisher": "aero",
"version": "1.0.0",
"tagline": "Warm paper, restrained clay",
"category": "Themes",
"icon": "📄",
"tags": ["light", "warm"],
"contributes": {
"themes": [
{ "label": "Paper Light", "uiTheme": "light", "path": "themes/paper-light.json" }
]
}
}No main, no activationEvents — the theme registers at install/enable time directly from the manifest.
themes/paper-light.json
{
"name": "Paper Light",
"type": "light",
"monaco": "vs",
"tokens": {
"bg": "#faf9f5",
"raised": "#ffffff",
"panel": "#f0eee6",
"text": "#1f1e1d",
"subtext": "#6b6a66",
"border": "#e5e3da",
"accent": "#c15f3c",
"accent-hover": "#a94e2f"
}
}This mirrors Aero's signature light palette — a good starting point to tweak into your own warm light theme.
Build & sideload
npx aero-ext package # → aero.paper-light-1.0.0.aero-ext
# Sideload via the Extensions view, then pick "Paper Light" from the theme list.Where to go next
- Manifest reference — every field these examples use.
- The
aero.*API — what Example 1's handler calls. - Publishing — push either example to the marketplace.