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

@tooark/code

v1.3.0

Published

Tooark Code — a code editor (`<ark-code-editor>`) based on CodeMirror 6 (supporting JSON, JavaScript, and YAML), featuring code completion, formatting, and token-based theming

Readme

@tooark/code

npm License

<ark-code-editor>: a CodeMirror 6 editor as a Custom Element — JSON, JavaScript and YAML with completions, formatting, indentation and line-ending options, themed by the Tooark tokens.

🌍 Languages: USA Flag English (this file) · Brazil Flag Português


Contents


📖 Overview

The @tooark/code package provides:

  • language json / javascript / yaml / text, line numbers, folding, search (Ctrl+F), bracket matching, active line, placeholder, readonly, wrap, min-height;
  • Tab indents (Shift+Tab outdents; Esc then Tab leaves the editor), indent-style spaces or tabs, indent-size, line-ending auto/lf/crlf converted at the value boundary;
  • completions: the language's own, variableKeys after {{, completions (words in any language) and completionSource; autocomplete="false" turns them off;
  • optional, off until you pass them: variables paints each {{key}} with its variable's intent (free-form scope, hover tooltip with scope and value), mark-unknown-variables flags keys that are not defined, and single-line turns the editor into a one-line field at control height (size), Enter emitting ark-submit;
  • format() and Shift+Alt+F: JSON built in with the configured indentation, other languages through the formatter hook (Prettier stays in the app);
  • chrome on the --ark-color-* tokens with fallbacks, theme="auto" following the page at runtime; createCodeEditor engine without the element;
  • CodeMirror packages as peer dependencies, so the page keeps one copy of @codemirror/state.

🔧 Installation

pnpm add @tooark/code @codemirror/state @codemirror/view @codemirror/language @codemirror/commands @codemirror/search @codemirror/autocomplete @codemirror/lang-json @codemirror/lang-javascript @codemirror/lang-yaml @lezer/highlight

The CodeMirror packages are peer dependencies: your page keeps a single copy of each, and you choose the versions.


⚙️ Configuration

Register the element once; the editor styles itself through CodeMirror themes that read the --ark-color-* tokens (with fallbacks, so it works without @tooark/web-components):

import { registerTooarkCode } from "@tooark/code";

registerTooarkCode();

In React, Vue or Angular use the tag directly (the framework READMEs show how); a JS property the framework assigns before this call, such as value bound on the tag, is applied when the element upgrades, so the order does not matter.


📦 Components

ark-code-editor

  • Attributes: language (json | javascript | yaml | text), readonly, placeholder, min-height (default 8rem), line-numbers and fold (on; "false" turns off), wrap, indent-style (space | tab), indent-size (default 2), line-ending (auto | lf | crlf), tab-indent and autocomplete (on; "false" turns off), mark-unknown-variables, single-line, size (xs … xl, default md: font and side padding, plus the height in single-line), theme, aria-label (names the editable content, CodeMirror's role="textbox"), testid.
  • Properties: value, variableKeys, variables, completions, completionSource, formatter, canFormat, resolvedLineEnding, resolvedTheme, view (the EditorView), and one per attribute except aria-label and testid; methods format(), focus().
  • Events: change (detail: { value }, user edits only), ark-format-error (detail: { error }), ark-submit (detail: { value }, Enter in single-line).
  • Keys: Ctrl/Cmd+F search, Ctrl/Cmd+Z undo, Ctrl+Y redo (Cmd+Shift+Z on macOS), Ctrl+Space completions, Shift+Alt+F format, Tab/Shift+Tab indent, Esc+Tab leave, Ctrl+M (Shift+Alt+M on macOS) toggles CodeMirror's tab-focus mode.
  • Hooks: the CodeMirror root carries data-ark="code-editor" and the testid as data-testid; each painted variable data-ark="code-editor-variable" with data-key; its tooltip data-ark="code-editor-variable-tooltip".

Scoped variables

Nothing changes until the app passes variables or sets mark-unknown-variables; variableKeys alone still only completes.

  • variables: ArkCodeVariable[], one { key, scope?, intent?, value? } per key. The library knows no scope: scope is any name the app uses, and when a key exists in several scopes the app resolves the precedence and sends only the winner (a repeated key keeps its first entry).
  • Each {{key}} (inner spaces allowed; keys use letters, digits, _, ., - and $) becomes <span class="cm-ark-variable cm-ark-variable-<intent>" data-key data-scope data-intent> with the intent's soft background and text (--ark-color-<intent>-soft/-soft-fg, default primary), also inside JSON strings, and each variable stays a single span. The distinct hues are info, success, warning/primary and danger (which also marks unknown keys); secondary and neutral read close to the text color. For more scopes, or your own palette, override a scope's colors with CSS, e.g. ark-code-editor .cm-ark-variable[data-scope="global"] { background: …; color: … }.
  • A variable with scope or value shows a hover tooltip with the scope (in its intent) and the value; the completion after {{ shows the scope as detail and the value as info. All of that text is the app's: leave value out for secrets.
  • mark-unknown-variables: a {{key}} found in neither variables nor variableKeys gets cm-ark-variable-unknown and data-unknown, painted danger with a wavy underline (not color alone).

Single-line field

single-line makes a field such as a URL bar: the height of the controls of the same size (it lines up with ark-button and ark-input), no gutters and no active line, Enter emits ark-submit instead of breaking the line (when the completion list is open, Enter accepts the completion), pasted line breaks are removed as in an <input>, Tab leaves the field and Ctrl/Cmd+F is left to the browser. Turning it on over a multi-line text joins the lines without a change. Variables and completions work the same.

Engine

  • createCodeEditor(parent, options) → { view, getValue, setValue, setLanguage, setTheme, setReadonly, setPlaceholder, setLineNumbers, setFold, setWrap, setMinHeight, setIndent, setLineEnding, resolvedLineEnding, setTabIndent, setAutocomplete, setVariableKeys, setVariables, setMarkUnknownVariables, setSingleLine, setSize, setCompletions, setCompletionSource, setFormatter, format, canFormat, resolvedTheme, focus, destroy }; the options mirror the attributes and properties, plus onChange, onFormatError and onSubmit.
  • resolveCodeTheme(theme, element).
  • Types: ArkCodeEditorInstance, ArkCodeEditorOptions, ArkCodeVariable, ArkCodeLanguage, ArkCodeTheme, ArkCodeIndentStyle, ArkCodeLineEnding, ArkCodeCompletion, ArkCodeCompletionSource, ArkCodeFormatter.

📝 Usage examples

A JSON body editor with variable completions

const editor = document.querySelector("ark-code-editor")!;
editor.setAttribute("language", "json");
editor.setAttribute("indent-size", "4");
editor.variableKeys = ["baseUrl", "token", "user.id"]; // offered after {{
editor.value = JSON.stringify(body, null, 4);
editor.addEventListener("change", (event) => save((event as CustomEvent<{ value: string }>).detail.value));

formatButton.hidden = !editor.canFormat;
formatButton.addEventListener("click", () => editor.format()); // also Shift+Alt+F

A URL field with scoped variables

<ark-code-editor id="url" single-line mark-unknown-variables placeholder="{{baseUrl}}/path"></ark-code-editor>
const url = document.querySelector("ark-code-editor")!;
// Precedence between scopes is resolved by the app: one entry per key.
url.variables = [
  { key: "baseUrl", scope: "global", intent: "info", value: "https://api.example.com" },
  { key: "token", scope: "environment", intent: "success" }, // no value: kept out of the tooltip
  { key: "userId", scope: "local", intent: "primary", value: "42" },
];
url.value = "{{baseUrl}}/users/{{userId}}";
url.addEventListener("ark-submit", (event) => send((event as CustomEvent<{ value: string }>).detail.value));
/* your own color for one scope, instead of an intent */
ark-code-editor .cm-ark-variable[data-scope="environment"] {
  background: #ecfeff;
  color: #0e7490;
}

YAML with schema keys and an app formatter

import { dump, load } from "js-yaml"; // your dependency, not the library's

const editor = document.querySelector("ark-code-editor")!;
editor.setAttribute("language", "yaml");
editor.setAttribute("line-ending", "lf");
editor.completions = [
  { label: "apiVersion", type: "keyword" },
  { label: "kind", type: "keyword" },
  { label: "metadata" },
];
editor.formatter = (value) => dump(load(value), { indent: editor.indentSize });
editor.addEventListener("ark-format-error", (event) => toast.error(String((event as CustomEvent).detail.error)));

📋 Dependencies

Installed automatically unless marked as peer; peer dependencies are yours to install (the ranges are what the package declares).

| Package | Version | Description | | ------------------------------------------------------------------------------------------ | ------------- | --------------------------------------------------------- | | @tooark/tokens | ^1.3.0 | Design tokens (colors, sizes, motion) and primitive types | | tslib | ^2.8.1 | TypeScript runtime helpers | | @codemirror/autocomplete | >=6 (peer) | Completions and bracket closing | | @codemirror/commands | >=6.6 (peer) | Keymaps, history, indentation commands | | @codemirror/lang-javascript | >=6 (peer) | JavaScript language and completions | | @codemirror/lang-json | >=6 (peer) | JSON language | | @codemirror/lang-yaml | >=6 (peer) | YAML language | | @codemirror/language | >=6 (peer) | Language support, folding, indentation | | @codemirror/search | >=6 (peer) | Search panel and selection matches | | @codemirror/state | >=6 (peer) | Editor state (one copy per page) | | @codemirror/view | >=6.27 (peer) | Editor view and DOM | | @lezer/highlight | >=1 (peer) | Syntax highlight tags |


🪪 Contributing

Contributions are welcome! Open issues and pull requests in the Tooark/web-components repository; CONTRIBUTING.md covers the workflow, the commit convention and the checklist. @tooark/code is released in lockstep with every other @tooark/* package.


📄 License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.