AthasAthasDocs

Search documentation

Find a guide or reference page.

DocsCustomization

Extensions

Browse, install, develop, and publish Athas extensions

On this page9 sections

Athas extensions add language tooling, snippets, themes, icons, keymaps, databases, integrations, skills, and managed AI agents without making the core editor carry every integration by default.

Install and uninstall extensions from Settings > Extensions in Athas. The public Extensions catalog shows the same marketplace entries from the website.

How Extensions Work

Each Athas extension ships an extension.json manifest. Athas reads the manifest to register languages, snippets, themes, icons, databases, integrations, agents, commands, and managed tools. Integration extensions can also ship a constrained JavaScript entrypoint.

The preferred shape is close to VS Code's manifest model: stable editor contributions live under contributes, while managed runtime tools live under capabilities. Existing legacy fields such as iconThemes and databaseProviders are still supported for compatibility, but new extension manifests should use icons and databases.

Athas does not run arbitrary VS Code extension code. It can reuse and normalize declarative assets such as languages, snippets, themes, icons, and tool metadata, but full VS Code extension-host API compatibility is a separate problem.

Start Here

  1. Clone the Athas repository.
bash
git clone https://github.com/athasdev/athas.git
cd athas
  1. Create a folder under extensions/official/ for Athas-maintained extensions, or extensions/community/<publisher>/ for community-maintained extensions.
txt
extensions/
  official/
    my-language/
      extension.json
  community/
    acme/
      my-language/
        extension.json
  1. Add an extension.json manifest.
json
{
  "$schema": "https://athas.dev/schemas/extension.json",
  "id": "athas.my_language",
  "name": "My Language",
  "displayName": "My Language",
  "version": "1.0.0",
  "description": "Language tooling for My Language.",
  "publisher": "Athas",
  "engines": {
    "athas": ">=0.7.0"
  },
  "categories": ["Language"],
  "contributes": {
    "languages": [
      {
        "id": "my_language",
        "extensions": [".mylang"],
        "filenames": ["MyLangfile"],
        "filenamePatterns": ["*.mylang.json"],
        "aliases": ["My Language"]
      }
    ]
  },
  "activationEvents": ["onLanguage:my_language"]
}
  1. Add tooling under capabilities only when the extension owns it.
json
{
  "capabilities": {
    "lsp": {
      "name": "my-language-server",
      "runtime": "node",
      "package": "my-language-server",
      "args": ["--stdio"]
    },
    "formatter": {
      "name": "my-language-format",
      "runtime": "node",
      "package": "my-language-tools",
      "args": ["format", "--stdin-filepath", "${file}"]
    }
  }
}

Supported managed runtimes are bun, node, python, go, rust, and binary.

Manifest Fields

Use contributes for editor-visible declarations:

json
{
  "contributes": {
    "languages": [],
    "snippets": [],
    "themes": [],
    "icons": [],
    "databases": [],
    "integrations": [],
    "agents": [],
    "commands": [],
    "keybindings": []
  }
}

Language contributions can match by extension, exact filename, or filename pattern:

json
{
  "id": "jsonc",
  "extensions": [".jsonc"],
  "filenames": ["tsconfig.json", "jsconfig.json"],
  "filenamePatterns": ["tsconfig.*.json", "jsconfig.*.json"]
}

Use capabilities for managed tools that Athas installs and launches:

  • lsp: language server launched over stdio
  • formatter: formatter command
  • linter: linter command
  • grammar: parser and highlight-query asset metadata

For JavaScript or TypeScript language servers, declare companion packages in packages when the server expects them next to the primary package. Athas installs those packages into managed tool storage and resolves the launch path again when the tool starts.

Marketplace Flow

The marketplace is registry-driven:

  1. You add or edit an extension folder under extensions/official/ or extensions/community/ in athasdev/athas.
  2. You run the extension preparation scripts.
  3. The scripts stage generated CDN output under extensions/generated/cdn/.
  4. You open a pull request with the extension source and feature tooling changes. Generated CDN output is disposable and ignored.
  5. CI validates the manifests and catalog files.
  6. After merge, the deploy workflow syncs generated extension manifests, packages, and catalog files to https://athas.dev/extensions.
  7. Athas reads https://athas.dev/extensions/manifests.json and shows the extension in Settings > Extensions. The website catalog reads index.json and shows it on Extensions.

There is no separate marketplace admin step in Athas right now. If the extension is in the monorepo extension source folder, generated into the CDN catalog, merged, and deployed, it appears in the marketplace.

Local Validation

Run these commands from the Athas repository root:

bash
bun run extensions:package:databases -- --build  # only needed after database sidecar changes
bun run extensions:prepare
bun run extensions:validate

Commit the extension source and script changes:

bash
git add extensions src/features/extensions
git commit -m "Add My Language extension"

If you are testing against a local Athas app checkout, serve the extension marketplace directory and point Athas at it:

bash
bun run extensions:prepare
bunx serve extensions/generated/cdn -l 3001
VITE_PARSER_CDN_URL=http://localhost:3001 bun run dev
VITE_PARSER_CDN_URL=http://localhost:3001 ATHAS_EXTENSIONS_CDN_URL=http://localhost:3001 bun run tauri dev

Then open Athas and go to Settings > Extensions. Local changes should appear from your local server instead of the production marketplace.

Installation Behavior

Language extensions usually install the runtime tools declared in capabilities. For example, a Node LSP is installed into Athas-managed tool storage when the user clicks Install.

Theme, icon, and integration extensions are packaged by src/extensions/tooling/package-extensions.ts; the script writes installation.downloadUrl, size, and checksum into the manifest and creates a tarball under generated CDN output. The packaging script reads both top-level contributions and their matching contributes fields.

Agent extensions declare an agents contribution or contributes.agents. The contribution describes the ACP command Athas should detect, how to launch it, and optional managed installation metadata. The app reads those contributions from manifests.json; agent names and install commands should not be hardcoded in Athas.

SQLite is built into Athas because it is the default local-file database path. Other database providers, such as DuckDB, PostgreSQL, MySQL, MongoDB, and Redis, are normal marketplace extensions: their manifests declare databases or contributes.databases, their sidecar binaries are packaged under the extensions CDN, and users install or uninstall them from Settings > Extensions.

Integration Extensions

Integration extensions are executable marketplace packages, but they do not run in the editor process and cannot import Athas application code. Their single-file main entrypoint runs in an isolated module worker with direct browser networking disabled. All access to Athas goes through the extension API and the permissions declared in the manifest.

json
{
  "id": "acme.incidents",
  "name": "incidents",
  "displayName": "Acme Incidents",
  "description": "Inspect active incidents from Athas.",
  "version": "1.0.0",
  "publisher": "Acme",
  "categories": ["Integration"],
  "integrations": [
    {
      "id": "incidents",
      "name": "Acme Incidents",
      "kind": "observability"
    }
  ],
  "main": "main.js",
  "permissions": {
    "network": ["https://api.acme.example"],
    "secrets": true,
    "workspace": "read",
    "openExternal": true
  }
}

Available permissions are:

  • network: HTTP origins the extension may call through api.http
  • secrets: access to secure storage scoped to the extension ID
  • workspace: "read": the current root, repository, active file path, and Git remotes
  • openExternal: permission to open an HTTP or HTTPS link in the default browser

The public API registers namespaced commands and sidebar views. Views return serializable UI nodes, so extensions reuse Athas buttons, inputs, badges, lists, loading states, and error states instead of bringing their own React components, HTML, styles, or scripts.

js
const viewId = "acme.incidents.overview";

export async function activate(api) {
  let incidents = [];

  api.commands.register({
    id: "acme.incidents.refresh",
    title: "Refresh incidents",
    async run() {
      const response = await api.http.request({
        url: "https://api.acme.example/incidents",
      });
      incidents = JSON.parse(response.body);
      api.views.invalidate(viewId);
    },
  });

  api.sidebar.registerView({
    id: viewId,
    title: "Incidents",
    icon: "warning-circle",
    render: () =>
      api.ui.screen(
        { title: "Incidents" },
        api.ui.list(
          ...incidents.map((incident) =>
            api.ui.listItem({
              title: incident.title,
              badges: [{ label: incident.status, tone: "warning" }],
            }),
          ),
        ),
      ),
  });
}

Use extensions/sdk/athas-extension-api.d.ts for the API types. extensions/official/gitlab and extensions/official/sentry are complete reference packages. Bundle dependencies into main.js; relative imports are not available from an installed entrypoint.

Categories

  • Language: language registration, LSP, formatter, linter, snippets
  • Agent: ACP-compatible command-line coding agents
  • Integration: external services with constrained commands and structured UI
  • Theme: editor color themes
  • Icon Theme: file icons
  • Snippets: reusable snippets
  • Keymaps: keyboard shortcut presets
  • Formatter: standalone formatter contribution
  • Linter: standalone linter contribution
  • Other: everything else

Publishing

Open a pull request against athasdev/athas with your changes under extensions/ and src/features/extensions/ when tooling changes are needed. CI validates manifests and generated registry files. Once merged and deployed, the extension appears in the public Extensions catalog and inside Athas under Settings > Extensions.