Aksel Builder logo

Aksel Builder

Organization
navikt
aksel-builder

Build and refactor UI with Aksel, Nav's design system. Use for frontend tasks involving Aksel, Nav/Navikt, or @navikt/ds- and @navikt/aksel-packages, and for Figma-to-code with Aksel. Covers components, layout, tokens, theming, icons, Tailwind, accessibility, and migrations. Do not use when the user opts out of Aksel.

Overview

Publishernavikt
Repositorycopilot
Skill nameaksel-builder
Stars
60
Forks
16
Bundled files
11
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 11 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by navikt on GitHub. Read the source before you install it.

Installation

Install the Aksel Builder AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/navikt/copilot/tree/main/skills/aksel-builder
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/navikt/copilot.git /tmp/copilot
mkdir -p .claude/skills
cp -r /tmp/copilot/skills/aksel-builder .claude/skills/aksel-builder
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Aksel Builder in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Aksel Builder on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Aksel Builder is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Aksel design system skill

Mission

Build correct, accessible, production-quality UI with the Aksel design system (Nav). Lead the user to the right component, token, and primitive — and back every choice with the Aksel MCP server, not memory. Its 5 tools and 4 resources combine cached live docs from aksel.nav.no with token, icon, and migration catalogs bundled with the server. Check the project's installed versions before applying newer APIs. Aim for the fewest correct calls.

Design for the user's work

Start with the affected user's job and workflow. For applications where people carry out work, give working content and the next meaningful action priority. Derive navigation from workflows rather than project documents, hypotheses, or capability lists. Keep explanations, status, and history where they help people choose, perform, or check the work; disclose other detail when needed. Remove filler while preserving context needed for informed decisions and accessibility. Reports and information-led views are appropriate when reading, comparing, or monitoring is the user's job. Use the existing product direction and Aksel components to support that job; no single layout fits every workflow.


MCP-First rule (hard rule)

Never generate, edit, or debug Aksel code from training memory alone.

Aksel moves fast — token names, props, and whole components change between majors, and your weights are stale. Before writing any import, prop, token, or icon name:

  1. Confirm it exists and how it's used via the MCP.
  2. Never invent doc paths, prop names, token names, or icon exports.
  3. Verified sources win over memory. The MCP describes current docs and its bundled catalogs, not necessarily the project's installed version. Resolve mismatches against installed package types/exports and version-specific documentation. If no source confirms an API, say what you tried — don't fall back to a guess.

This one rule prevents the most common failure: confidently shipping an Aksel API that no longer exists.


Preflight: is the MCP available?

This skill is built around the Aksel MCP. Before your first lookup, check whether the aksel_* tools exist, and branch:

✅ MCP available (strongly preferred). Use the tools below for structured props, token values, and icon names. They do not inspect the consuming project's dependencies: confirm version-sensitive APIs against the installed packages.

The environment must allow https://aksel-mcp.nav.no. If access is blocked, report it and use the fallback below; don't work around access restrictions.

❌ MCP not available → recommend installing it, then fall back to fetching docs.

  1. Recommend the MCP. Find io.github.navikt/aksel-mcp in Nav's registry (https://mcp-registry.nav.no) and use the client's installation flow. The endpoint is https://aksel-mcp.nav.no/mcp. For VS Code, .vscode/mcp.json uses:
json
{
  "servers": {
    "io.github.navikt/aksel-mcp": {
      "type": "http",
      "url": "https://aksel-mcp.nav.no/mcp"
    }
  }
}

Merge the entry into existing configuration; don't replace other servers. Other clients use different configuration keys; see the VS Code format reference.

  1. Until it's installed, fall back to the public LLM docs over HTTP. Start from the index at https://aksel.nav.no/llm.md — it lists every page as an individual .md file — then fetch the specific .md page you need. These are the docs used by the MCP's documentation tools, not a replacement for its structured token/icon catalogs. Inspect installed exports and token files when prose is insufficient; never invent paths, props, tokens, or icon names.

Tool → manual-fetch fallback

When the MCP is absent, map each tool to a direct fetch:

MCP tool (preferred)Without MCP, fetch instead
aksel_find_docs (docs)https://aksel.nav.no/llm.md index → follow the matching .md link
aksel_get_docthe page's .md URL directly (e.g. https://aksel.nav.no/komponenter/core/button.md)
aksel_get_component_infothe component's .md page — it documents props & usage (prose, not a structured table)
aksel_get_token_detailshttps://aksel.nav.no/grunnleggende/styling/design-tokens.md
aksel_find_iconshttps://aksel.nav.no/komponenter/ikoner.md
aksel_find_docs (migrations)https://aksel.nav.no/grunnleggende/kode/codemods-config.md; discover the version-specific guide in llm.md

Prefer fetching individual .md pages over the full collection — only pull llm.md (or komponenter.md) when you need to discover the right page.


Tool capability matrix

Route by intent. Pick the narrowest tool. The default loop is Find → Fetch.

IntentToolKey argsReturnsCommon failure to avoid
Find the doc/component path for a topicaksel_find_docs{ query, kind:"docs" }ranked results[] with pathGuessing a path instead of searching first
Read a full doc pageaksel_get_doc{ path } (exact, from find)markdownHand-writing a path; must start /, end .md
Get a component's props/APIaksel_get_component_info{ component } slug or pathstructured propsReading prose docs when you need the prop table
Look up a design token's value/usageaksel_get_token_details{ tokenName }value, accessors, semanticsUsing find_docs for tokens — wrong tool
Browse tokens by keywordaksel_find_docs{ query, kind:"tokens" }token catalog matchesThen call get_token_details for the exact one
Find an iconaksel_find_icons{ keyword, category?, variant? }icons[] with nameAssuming an icon export name from memory
Find a migration/codemodaksel_find_docs{ query, kind:"migrations" }codemods + run commandUsing kind:"docs" for upgrade questions

Resources (read directly when you want the whole catalog, not a search): aksel-docs://index, aksel-tokens://catalog, aksel-icons://category-catalog, aksel-migrations://catalog.


Core workflow: Find → Fetch → Build → Validate

Most tasks need 2–4 MCP calls.

  1. Find — aksel_find_docs({ query }) with 1–2 keywords (component names work best; Norwegian and English both work). Use the returned path; never build one yourself. Switch kind: tokens/colors/spacing → "tokens", upgrades/codemods → "migrations".
  2. Fetch — get_doc (usage, examples, props as prose), get_component_info (props as JSON), get_token_details (one token), find_icons (then map name → ${name}Icon).
  3. Build — use semantic tokens for design-system styling; primitive props, CSS, and the project's existing Tailwind utilities are valid choices, subject to local rules (tokens-styling.md); reach for layout primitives before custom CSS (primitives-layout.md); add the a11y props Aksel requires (accessibility.md).
  4. Validate — run the checklist at the end of this file.

Decision tree: route the task

The Find → Fetch → Build → Validate loop is how you work; this is where to go for a given task. Orient once, then take the matching branch(es). Load a reference the first time a task touches its domain — don't preload all of them. All reference files live in references/ (e.g. references/components.md).

0. Orient (once per task). Glance at the project before building:

  • Are the aksel_* MCP tools available? If not, see Preflight above — encourage installing the MCP, and until then fall back to fetching https://aksel.nav.no/llm.md.
  • Is Aksel installed and which major version? Check package.json for @navikt/ds-react (its version drives which API is current). Unsure about setup, imports, or SSR/RSC? → load setup-and-imports.md.

Then branch by intent (reference to load → tools to call):

If the task is…LoadThen call
Pick/build a component (form, modal, table, …)components.mdfind_docs → get_component_info → get_doc (usage) → build
Implement a Figma design → Aksel codefigma-to-code.mdFigma MCP (get_design_context/get_screenshot) → map to Aksel via the aksel_* tools → build
Lay out / space / make responsiveprimitives-layout.mdbuild with primitives (get_component_info for a primitive's API)
Color / token / spacing value / Tailwind stylingtokens-styling.mdget_token_details (browse via find_docs kind:"tokens")
Light/dark mode or base colortheming.mdget_component_info / get_doc for Theme when not already verified
An iconicons.mdfind_icons → map name → ${name}Icon
Accessibility / labels / a11y reviewaccessibility.mdget_component_info to find the label/description props
Upgrade / codemod / “why is this deprecated?”migrations.mdfind_docs kind:"migrations"
Project setup / imports / packages / SSRsetup-and-imports.mdfind_docs kind:"docs" ("kom i gang")
A tool call misbehaves / returns nothingmcp-workflow.mdre-route per its recovery tables

Complex tasks chain branches. “Dark-mode contact form with a trash icon” touches components.md + tokens-styling.md + theming.md + icons.md + accessibility.md — load each as you reach that part, and build in that order (structure → style → theme → icons → a11y pass).


Reference files

The decision tree above says when to load each file; this is the index of what each contains. Load on demand to keep context small.


Call-budget & token conservation

  • Prefer Find → Fetch (2 calls) over scattershot searching; stop once you can build.
  • find_docs (kind:"docs") needs ≥ 3 characters; if it returns nothing, retry once with a single broader keyword (a component name) before changing approach.
  • Don't re-fetch a doc you already have. Don't echo raw tool JSON back — extract and build.
  • ≤ 4 calls is the target, not a limit. Still stuck after ~7? Stop and ask the user rather than guessing.

Final validation checklist

  • For changes to layout or interaction, the affected job was exercised on the rendered UI, including its result and relevant recovery states. Inspect hierarchy at the relevant viewport and whether explanation or navigation delays the work. Report anything that could not be inspected.
  • Aksel components and icons were confirmed via MCP or the documented fallback, and match installed versions.
  • Doc paths came from aksel_find_docs, aksel-docs://index, or llm.md — none were guessed.
  • Non-trivial props were checked with aksel_get_component_info or, in fallback mode, official docs and installed types.
  • Aksel tokens are verified; custom values have a real requirement rather than replacing an existing token.
  • Icon imports use the ${name}Icon export from @navikt/aksel-icons.
  • Required accessibility props are present (labels, descriptions, alt text).
  • Imports resolve against installed packages. React compatibility follows the app; React 17 compatibility is required when contributing to Aksel's published React library.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Aksel Builder AI skill do?

Build and refactor UI with Aksel, Nav's design system. Use for frontend tasks involving Aksel, Nav/Navikt, or @navikt/ds- and @navikt/aksel-packages, and for Figma-to-code with Aksel. Covers components, layout, tokens, theming, icons, Tailwind, accessibility, and migrations. Do not use when the user opts out of Aksel.

Why use Aksel Builder on TypingMind?

Because you install it once and use it with any model. Aksel Builder is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Aksel Builder in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/navikt/copilot/tree/main/skills/aksel-builder. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Aksel Builder?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Aksel Builder?

As many as you like. As long as a model supports skills, you can use Aksel Builder with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Aksel Builder AI skill free?

Yes. It is published on GitHub by navikt under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇