npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aardarch/aardink-web

v0.6.2

Published

The Aardink code editor for the browser: Compose Multiplatform on WebAssembly behind a Monaco-shaped API.

Readme

@aardarch/aardink-web

The Aardink code editor for the browser: Compose Multiplatform compiled to WebAssembly, behind a small Monaco-shaped API. It highlights Kotlin, TypeScript, JSON, TOML, XML, HTML, CSS and Markdown, and any language you register as a Monarch grammar. It has folding, find and replace, diagnostics, undo and redo, multiple cursors and column selection, bracket-pair colours, a minimap and sticky scroll, and six themes. It draws only the lines on screen, so a keystroke costs the same in a 5,000-line file as in a 50-line one.

Install

pnpm add @aardarch/aardink-web     # or: npm install @aardarch/aardink-web
pnpm add @aardarch/aardink-web@next   # the latest pre-release

The package is plain ES modules plus two .wasm files and a font. It needs a bundler that understands new URL('./file', import.meta.url), which Vite, webpack 5 and Rollup all do. Each version is published from GitHub Actions with npm provenance.

Use

import { createEditor, preloadAardink } from '@aardarch/aardink-web';

preloadAardink(); // optional: start loading the WebAssembly module and the font early

const editor = await createEditor(document.getElementById('editor')!, (text) => save(text), {
  value: source,
  language: 'xml',
  theme: 'vscode-dark',
  wordWrap: 'on',
  minimap: { enabled: true },
});

editor.updateOptions({ readOnly: true });
editor.setDiagnostics([
  { line: 3, startColumn: 5, endColumn: 9, message: 'Unknown tag', severity: 'error' },
]);
const stop = editor.onDidChangeCursor((line, column) => showPosition(line, column));
// The language's own diagnostics (shown until you call setDiagnostics; null goes back to them).
const off = editor.onDidChangeDiagnostics((markers) => showProblems(markers));
const savedAt = editor.getAlternativeVersionId(); // unsaved while it differs
editor.dispose();

setValue is for opening a file: it clears the undo history. A change the user should be able to undo, such as an assistant's rewrite, goes through replaceValue (the whole text) or Monaco's executeEdits (ranges). Either is one undo step that keeps the history before it, and changes only what differs, so carets and folds in unchanged text stay put:

editor.replaceValue(rewritten); // undo() brings the old text back
editor.executeEdits('assistant', [
  { range: { startLineNumber: 3, startColumn: 1, endLineNumber: 3, endColumn: 9 }, text: '<button/>' },
]);

A language of your own is a Monarch grammar registered before use, optionally extending a built-in language's completions, diagnostics and folding, with Monaco's defineTheme for its colours:

import { defineTheme, registerLanguage } from '@aardarch/aardink-web';

await registerLanguage(
  { id: 'toy', extends: 'xml', grammar: { tokenizer: { root: [[/\bshout\b/, 'keyword']] } } },
  {
    triggerCharacters: ['{'], // besides XML's
    provideCompletionItems: (text, line, column) => [{ label: 'shout', kind: 'element' }],
  },
);
await defineTheme('toy-dark', { base: 'vs-dark', inherit: true, rules: [{ token: 'keyword', foreground: 'ff00ff' }] });

Completion items take Monaco's filterText, sortText and range too, and inheritCompletions: false in the definition leaves out the extended language's completions (XML's are Android-flavoured) while keeping its diagnostics and folding. A hover can carry an example, shown as code.

The editor fills its container, so give the container a size. createEditor is async because the first call loads the WebAssembly module (about 13 MB, 4.7 MB gzipped); every editor on the page shares that one module. If that load fails, the call rejects and the next call loads again (though Chrome keeps a failed module download until the page is reloaded). See index.d.ts for the full API, and the integration guide for how Monaco's options and calls map onto it.

Vite

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  // The dev-server pre-bundler would move the package into .vite/deps and break the
  // new URL(..., import.meta.url) references the loader relies on.
  optimizeDeps: { exclude: ['@aardarch/aardink-web'] },
  build: { target: 'es2022', chunkSizeWarningLimit: 3500 },
});

vite build prints two harmless warnings about node:fs and node:url being externalised: the Kotlin loader has Node and Deno branches that never run in a browser. Serve .wasm with Content-Type: application/wasm.

The page

  • Mount an editor where it stays: do not move its container to another place in the DOM, as a Svelte {#key} block or a React portal can. Dispose it and mount a new one instead.
  • On phones, <meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content"> keeps the editor above the soft keyboard.

Browser support

Chrome and Edge 119+, Firefox 120+, Safari 18.2+: the module needs WebAssembly garbage collection and exception handling.

Known limitations

Read these before adopting the package; the integration guide has the measurements and the device checklist.

  • A disposed editor is not fully released (about 275 KB each) until Aardink moves to Compose Multiplatform 1.13. Reuse one editor with setValue and updateOptions rather than mounting one per view.
  • A theme rule's background is ignored; its foreground and fontStyle apply.

Licence

Apache-2.0. The bundled JetBrains Mono font is under the SIL Open Font License 1.1; see JETBRAINS_MONO_OFL.txt.