Agent skill

Jaspr JS Interop

by rodydavis in rodydavis/signals.dart

Rules for calling JavaScript from Jaspr web apps in Dart: which interop libraries to import in server, static and client modes, and how to wrap functions, objects and libraries.

Apache-2.0Auto-check passedFrontend & Design

Install Jaspr JS Interop

skills CLI
$ npx skills add rodydavis/signals.dart --skill jaspr-js-interop -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install rodydavis/signals.dart jaspr-js-interop --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/rodydavis/signals.dart.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/jaspr-js-interop .claude/skills/jaspr-js-interop && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
jaspr-js-interop
GitHub stars
819
Token cost
~823 tokens
SKILL.md length
197 words
Files
1
Skills in repo
15
Repo updated
First seen
Licence
Apache-2.0

At a glance

Rules for calling JavaScript from Jaspr web apps in Dart: which interop libraries to import in server, static and client modes, and how to wrap functions, objects and libraries.

  • Wrapping an existing JavaScript library in a Jaspr web app
  • SKILL.md covers Rules for JS Interop and Usage Examples
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • Calling browser-native APIs from Dart code that is also pre-rendered on the server

What it does

Jaspr apps can compile to JavaScript or WebAssembly, so reaching raw JS needs Dart's explicit `js_interop`. The import rules depend on the mode. In server or static mode the code must always import `package:universal_web/js_interop.dart`, a stub that keeps server-side compilation working, and must wrap any interop call in an `if (kIsWeb)` check so pre-rendering does not throw. In client mode `dart:js_interop` can be imported directly. For standard browser APIs such as the window, document and DOM nodes, the skill points to `universal_web/web.dart`, or `package:web/web.dart` in client mode, instead of hand-written wrappers.

Usage examples show three patterns. A top-level global JS function is bound with `@JS()` and an external declaration. A third-party JS library is wrapped by an extension type over `JSObject`, with external methods for each call. A plain JS object literal, such as a chart configuration, is modeled as an `@anonymous` extension type.

When your agent uses it

  • Wrapping an existing JavaScript library in a Jaspr web app
  • Calling browser-native APIs from Dart code that is also pre-rendered on the server
  • Passing a configuration object into a JS function from Dart

Example prompts

  • “Wrap the window.Analytics library so I can call trackPage from my Jaspr component.”
  • “My static Jaspr build throws on window access during pre-rendering. Fix the interop imports.”
  • “Define a Dart type for the chart config object I pass to the JS charting library.”

Requirements

  • A Jaspr project written in Dart

What it can do on your machine

Read from SKILL.md and the folder at commit 81d64e8. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are dart).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Jaspr JS Interop loads about 823 tokens when it runs. Until then it costs about 55 tokens; SKILL.md has 197 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~55
When it runs · the whole SKILL.md, loaded when a task matches
~823

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from rodydavis/signals.dart at commit 81d64e8, republished under its Apache-2.0 licence (© rodydavis). 197 words, ~823 tokens.

Download SKILL.mdSave it as .claude/skills/jaspr-js-interop/SKILL.md (or your agent's skills folder).
name
jaspr-js-interop
description
Effectively integrate with Javascript when building Jaspr web applications. Use this skill when wrapping an existing JS library, accessing browser-native APIs, or bridging code safely across environments.
metadata.jaspr_version
0.23.1

Rules for JS Interop

Dart makes accessing JavaScript simple using modern js_interop. Since Jaspr applications can be compiled to JavaScript or WebAssembly, utilizing Dart's explicit js_interop mechanism is required when you need to interface with raw JS variables, functions, or libraries.

1. Import Strategy
  • Rule 1: In server or static mode, you MUST ALWAYS import package:universal_web/js_interop.dart. It acts as a safe stub during server-side processing without breaking compilation.
  • Rule 2: In server or static mode, you MUST wrap any JS Interop execution in an if (kIsWeb) { ... } block to avoid throwing exceptions on the server during pre-rendering.
  • Rule 3: In client mode, you can directly import dart:js_interop.
  • Rule 4: For standard browser APIs (like window.innerHeight, document, DOM nodes), use package:universal_web/web.dart (or package:web/web.dart in client mode) instead of manually creating js_interop wrappers.

Usage Examples

Top Level Functions

To bind directly to a globally available JS function or object, use @JS():

dart
@JS()
external void alert(JSString message);

void showAlert() {
  if (kIsWeb) {
    // Make sure to convert Dart String types using .toJS
    alert('Hello from Dart!'.toJS);
  }
}

Wrapping Third-Party JS Libraries

To interact with specific Javascript Objects from external libraries, map an extension type wrapping JSObject.

dart
// Suppose there is a JS library available via `window.Analytics`
extension type Analytics._(JSObject _) implements JSObject {
  external void trackPage(JSString pageName);
  external JSNumber getVisitCount();
}

@JS('Analytics')
external Analytics get analytics;

void logCurrentPage() {
  if (kIsWeb) {
    analytics.trackPage('Home'.toJS);
    
    // Convert Javascript primitives back to Dart types using `.toDart`
    int visits = analytics.getVisitCount().toDartInt;
    print('Total visits: $visits');
  }
}

Anonymous JS Objects

If you need to pass a configuration object (a plain JS object literal {}) into a JS function, or receive one from JavaScript, define an @anonymous extension type.

dart
@JS()
@anonymous
extension type ChartConfig._(JSObject _) implements JSObject {
  external factory ChartConfig({
    JSString title,
    JSBoolean showLegend,
    JSArray<JSNumber> data,
  });

  external JSString get title;
  external JSArray<JSNumber> get data;
}

@JS()
external void renderChart(ChartConfig config);

void setupChart() {
  if (kIsWeb) {
    // Creating an anonymous JS object to pass into a JS function
    final config = ChartConfig(
      title: 'Monthly Sales'.toJS,
      showLegend: true.toJS,
      data: [10.toJS, 20.toJS, 30.toJS].toJS,
    );
    
    renderChart(config);

    // Reading properties from a JS object back to Dart types
    String title = config.title.toDart;
    List<double> rawData = config.data.toDart.map((e) => e.toDartDouble).toList();
  }
}

© rodydavis, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/jaspr-js-interop of rodydavis/signals.dart.

Open the folder on GitHubat commit 81d64e8

Compare with similar skills

Jaspr JS Interop next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Jaspr JS Interop compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Jaspr JS Interop this skillrodydavis/signals.dart819—~823Automated safety check: PassApache-2.0
Tabler Core JavaScripttabler/tabler42k—~1.4kAutomated safety check: PassMIT
@pierre/diffs Code Renderingpierrecomputer/pierre6.3k2 repos~803Automated safety check: PassApache-2.0
Tabler Astro Component Scriptstabler/tabler42k—~2.1kAutomated safety check: PassMIT
Tabler Bootstrap Component Rulestabler/tabler42k—~2.2kAutomated safety check: PassMIT
Pierre Trees File Treepierrecomputer/pierre6.3k—~473Automated safety check: PassApache-2.0

Similar skills

  • Guidance for changing the Tabler framework's own JavaScript in core/js: the tabler.js and tabler-theme.js bundles, the Bootstrap port and their tests.

    42k GitHub stars~1.4k tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • @pierre/diffs Code Rendering

    pierrecomputer/pierre

    Guides an agent through using @pierre/diffs to render syntax-highlighted files and diffs, and to build editing and review surfaces in React or plain JavaScript.

    6.3k GitHub starsUsed in 2 repos~803 tokens
    DevelopmentAuto-check passed
  • Rules for adding or fixing client-side scripts in Tabler's Astro components so the copied preview HTML stays readable, self-contained and runs in the right order.

    42k GitHub stars~2.1k tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Sets the file structure, typing and Data API pattern for writing a new Bootstrap-style JavaScript component class in Tabler's vendored port of Bootstrap's JS.

    42k GitHub stars~2.2k tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Pierre Trees File Tree

    pierrecomputer/pierre

    Use when an app uses @pierre/trees to render or control a file tree, including React, vanilla JavaScript, SSR, web components, selection, search, rename, drag…

    6.3k GitHub stars~473 tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • HTML Coder

    TokenRhythm/opensquilla

    Guides semantic, accessible HTML work: pages, forms, media and HTML5 APIs, plus how to deliver a runnable webpage project with a preview.

    7.1k GitHub stars~1.4k tokensUpdated today
    Frontend & DesignAuto-check passed

More from rodydavis/signals.dart

All 15 skills in this repo
  • Jaspr Component Fundamentals

    rodydavis/signals.dart

    Teaches the agent Jaspr's Flutter-like component model and typed HTML elements, with strict rules on build methods and helper syntax.

    819 GitHub stars~1.8k tokensUpdated 25 days ago
    Auto-check passed
  • Jaspr CSS-in-Dart Styling

    rodydavis/signals.dart

    Guides styling of Jaspr web components with the type-safe Styles API in Dart, covering @css annotations, inline styles and global stylesheets.

    819 GitHub stars~1.7k tokensUpdated 25 days ago
    Auto-check passed
  • Jaspr Pre-Rendering and Hydration

    rodydavis/signals.dart

    Sets the rules for static or server mode Jaspr apps in Dart, covering dual entrypoints, the client annotation and data hydration.

    819 GitHub stars~1.2k tokensUpdated 25 days ago
    Auto-check passed
  • Update Dart Examples Dependencies

    rodydavis/signals.dart

    Upgrades every package under ./examples to the repository's latest signals version, runs pub upgrade on third-party dependencies, and fixes the resulting analysis problems.

    819 GitHub stars~514 tokensUpdated 25 days ago
    Auto-check passed
  • Jaspr HTML Converter

    rodydavis/signals.dart

    Use when you need to convert / rewrite existing HTML (from a file or url) into Jaspr code.

    819 GitHub stars~378 tokensUpdated 25 days ago
    Auto-check passed
  • Dart Monorepo Coverage Booster

    rodydavis/signals.dart

    Runs, merges, and analyzes Dart and Flutter test coverage across a Melos monorepo, then targets the exact uncovered lines.

    819 GitHub stars~1.1k tokensUpdated 25 days ago
    Auto-check passed

Works with

Questions about Jaspr JS Interop

What does Jaspr JS Interop do?

Rules for calling JavaScript from Jaspr web apps in Dart: which interop libraries to import in server, static and client modes, and how to wrap functions, objects and libraries. Jaspr apps can compile to JavaScript or WebAssembly, so reaching raw JS needs Dart's explicit `js_interop`. The import rules depend on the mode.

When should I use Jaspr JS Interop?

Jaspr JS Interop fits situations like: wrapping an existing JavaScript library in a Jaspr web app; calling browser-native APIs from Dart code that is also pre-rendered on the server; passing a configuration object into a JS function from Dart.

How do I install Jaspr JS Interop in Claude Code?

Run `npx skills add rodydavis/signals.dart --skill jaspr-js-interop -a claude-code`. Or copy the skill folder (.agents/skills/jaspr-js-interop in rodydavis/signals.dart) into .claude/skills/jaspr-js-interop in your project. Claude Code loads it when a task matches its description.

How do I install Jaspr JS Interop in Codex?

Run `npx skills add rodydavis/signals.dart --skill jaspr-js-interop -a codex`. Or copy the skill folder (.agents/skills/jaspr-js-interop in rodydavis/signals.dart) into .agents/skills/jaspr-js-interop in your project. Codex loads it when a task matches its description.

Can I use Jaspr JS Interop in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add rodydavis/signals.dart --skill jaspr-js-interop -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/jaspr-js-interop, .gemini/skills/jaspr-js-interop, .github/skills/jaspr-js-interop and .opencode/skills/jaspr-js-interop in your project.

What does Jaspr JS Interop need to run?

SKILL.md names no scripts, command-line tools or credentials: Jaspr JS Interop is instructions for the agent only. Our summary lists: A Jaspr project written in Dart.

Does Jaspr JS Interop access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Jaspr JS Interop safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Jaspr JS Interop use?

Jaspr JS Interop is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Jaspr JS Interop use?

About 823 tokens (SKILL.md is roughly 3.3k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Jaspr JS Interop?

Skills that share tags, products or a category with Jaspr JS Interop: Tabler Core JavaScript (tabler/tabler, 42k stars), @pierre/diffs Code Rendering (pierrecomputer/pierre, 6.3k stars), Tabler Astro Component Scripts (tabler/tabler, 42k stars) and Tabler Bootstrap Component Rules (tabler/tabler, 42k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Jaspr JS Interop?

rodydavis (a GitHub user) maintains it in rodydavis/signals.dart, which has 819 GitHub stars. The repository holds 15 skills in this directory. The repository was last updated on September 14, 2026.

Source: rodydavis/signals.dart on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.