Agent skill

Zenrouter

by definev in definev/zenrouter

Implement and extend routing with zenrouter's Coordinator, RouteManifest, and RouteBinding APIs.

Apache-2.0Auto-check passedMobile

Install Zenrouter

skills CLI
$ npx skills add definev/zenrouter --skill zenrouter -a claude-code

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

GitHub CLI
$ gh skill install definev/zenrouter zenrouter --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/definev/zenrouter.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/zenrouter .claude/skills/zenrouter && 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
zenrouter
GitHub stars
102
Token cost
~4.3k tokens
SKILL.md length
1,049 words
Files
4
Skills in repo
1
Repo updated
First seen
Licence
Apache-2.0

At a glance

Implement and extend routing with zenrouter's Coordinator, RouteManifest, and RouteBinding APIs.

  • Works in 10 steps: Route Base Type → Single Coordinator → Modular Features → …
  • Nested coordinator
  • SKILL.md covers Before you edit, Mental model, Key Types and Patterns, plus 11 more sections
  • Calls dart

What it does

Zenrouter is an agent skill from definev/zenrouter. Implement and extend routing with zenrouter's Coordinator, RouteManifest, and RouteBinding APIs. Use when adding a route, feature module, layout, redirect, guard, nested coordinator, deep link, or programmatic navigation. Triggers on: route, router, routing, coordinator, CoordinatorModular, RouteModule, RouteModuleBinding, RouteManifest, RouteManifestFragment, RouteBinding, RouteBindingRegistry, NavigationPath, IndexedStackPath, BranchedStackPath, RouteLayout, parentId, parentLayoutKey, layoutKey, bindLayout…

Its SKILL.md is about 4.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files (for example `ADVANCED.md`, `MIXIN.md` and `NAVIGATION.md`).

It sits in Mobile, covering Cross-platform mobile apps. It works with Flutter. The repository describes itself as: The Ultimate Flutter/Dart Frontend Router for Every Navigation Pattern. The licence is Apache-2.0.

When your agent uses it

  • Nested coordinator
  • Programmatic navigation
  • CoordinatorModular
  • RouteModuleBinding

Example prompts

  • “/zenrouter”

Workflow steps

10 steps, taken from the step headings in SKILL.md.

  1. Route Base Type
  2. Single Coordinator
  3. Modular Features
  4. Route Definition
  5. Layout
  6. Navigation
  7. File-Based Routes
  8. File Structure (hand-written)
  9. Naming
  10. Adding a Feature: Checklist

What it can do on your machine

Read from SKILL.md and the folder at commit 8c536fc. 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

    Shell commands in SKILL.md call:

    • dart

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

  • Network

    Links to these hosts (documentation or services it may open):

    • pub.dev

    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

Zenrouter loads about 4.3k tokens when it runs. Until then it costs about 175 tokens; SKILL.md has 1,049 words of instructions outside code blocks.

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

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 definev/zenrouter at commit 8c536fc, republished under its Apache-2.0 licence (© definev). 1,049 words, ~4,291 tokens.

Download SKILL.mdSave it as .claude/skills/zenrouter/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
zenrouter
description
Implement and extend routing with zenrouter's Coordinator, RouteManifest, and RouteBinding APIs. Use when adding a route, feature module, layout, redirect, guard, nested coordinator, deep link, or programmatic navigation. Triggers on: route, router, routing, coordinator, CoordinatorModular, RouteModule, RouteModuleBinding, RouteManifest, RouteManifestFragment, RouteBinding, RouteBindingRegistry, NavigationPath, IndexedStackPath, BranchedStackPath, RouteLayout, parentId, parentLayoutKey, layoutKey, bindLayout, RouteUnique, RouteNotFound, parseRouteFromUri, push, pop, replace, navigate, recover, recoverUri, location, deep link, toUri, zenrouter, @ZenRoute, @ZenLayout, @ZenCoordinator.

ZenRouter Skill

This project uses zenrouter. Coordinator apps declare static topology in a RouteManifest and map IDs to RouteTarget constructors with RouteBinding. For new graphs, do not write a parseRouteFromUri switch.

Deep-dive references — read these only when you need the specific topic:

FileWhen to read
ADVANCED.mdFragments, typed IDs, deferred bindings, Coordinator-as-Module, tabs/branches, redirect/guard rules
MIXIN.mdRouteGuard, RouteRedirect, RouteDeepLink, RouteTransition, RouteQueryParameters, RouteRestorable
NAVIGATION.mdpush vs navigate vs replace, plus URI helpers (pushUri, recoverUri)

Before you edit

Inspect the repo, then follow one style:

What you seeWhat to do
@ZenRoute / @ZenLayout / routes.zen.dartFile-based. Add an annotated file under lib/routes/. Run dart run build_runner build. Never edit *.g.dart or routes.zen.dart.
RouteModuleBindingManifest-bound. Add a manifest node, a binding, and a route class.
parseRouteFromUri switch and no binding mixinParser-era. Add a switch case. Do not migrate onto a manifest unless asked.

Import package:zenrouter/zenrouter.dart (re-exports zenrouter_core).


Mental model

LayerOwnsMust not own
RouteManifestIDs, URI patterns, parentId, layout kindsWidgets, constructors, BuildContext
RouteBindingID → RouteTarget factory from RouteManifestMatchTopology, matching order
RouteTargetbuild(), layout, redirects, guardsURI matching

Matching and manifest.location(...) share the same pattern. toUri() must delegate to that helper — never hand-build a parallel path string.


Key Types

TypePurpose
RouteTarget + RouteUniquePresentation route; required for Flutter coordinator routes
RouteManifest<I>Immutable graph of routes + layouts; owns matching and reverse routing
RouteManifestFragment<I>One module's contribution; composed by CoordinatorModular
RouteBinding<I, T>Adapter from a matched ID to a RouteTarget
RouteBindingRegistry<I, T>Validated complete set of bindings for one manifest
RouteModuleBinding<T, I>Mixin on RouteModule / Coordinator — parseRouteFromUri = routeBindings.resolve
Coordinator<T>Flutter hub: paths, layouts, MaterialApp.router
CoordinatorModular<T>Delegates parsing to modules and composes their fragments
RouteModule<T>One feature's paths, layouts, and (via binding) URI parsing
NavigationPath<T>Mutable stack; one per layout group
IndexedStackPath<T> / BranchedStackPath<T>Tabs / stateful-shell branches — see ADVANCED.md
RouteLayout<T>Shell that wraps child routes
RouteNotFoundMarker mixin — not-found route keeps the requested URI

Patterns

Every manifest path starts with / and has no query or fragment.

PatternMatchesBinding reads
/shop/shop—
/products/:id/products/42match.pathParameters['id']!
/docs/...:slugs/docs, /docs/a/bmatch.restParameters['slugs']! (List<String>)
/docs/...:slugs/:id/docs/a/b/startrest slugs + path id
  • :name — one segment. ...:name — zero or more segments. At most one rest parameter.
  • Parameter names: ^[A-Za-z_][A-Za-z0-9_]*$. No duplicate names in one pattern.
  • More literal segments win. A rest pattern loses to a non-rest pattern. Equal-specificity overlaps fail construction.

Query strings are not part of the pattern. Read match.uri.queryParameters in the binding if needed.


1. Route Base Type

dart
abstract class AppRoute extends RouteTarget with RouteUnique {
  @override
  Widget build(covariant Coordinator coordinator, BuildContext context);
}

2. Single Coordinator

Use when the app is one graph (no feature modules). Mix RouteModuleBinding and do not override parseRouteFromUri.

dart
enum AppRouteId { home, product }

class AppCoordinator extends Coordinator<AppRoute>
    with RouteModuleBinding<AppRoute, AppRouteId> {
  static final manifest = RouteManifest<AppRouteId>(
    name: 'app',
    idCodec: RouteIdCodec.enumValues(AppRouteId.values),
    routes: [
      RouteManifestRoute(id: AppRouteId.home, path: '/'),
      RouteManifestRoute(id: AppRouteId.product, path: '/products/:id'),
    ],
  );

  static const location = AppCoordinatorLocation();

  @override
  late final routeBindings = manifest.bind<AppRoute>(
    bindings: [
      RouteBinding(id: AppRouteId.home, create: (_) => HomeRoute()),
      RouteBinding(
        id: AppRouteId.product,
        create: (match) => ProductRoute(id: match.pathParameters['id']!),
      ),
    ],
    notFound: NotFoundRoute.new,
  );
}

final class AppCoordinatorLocation {
  const AppCoordinatorLocation();

  Uri get home => AppCoordinator.manifest.location(AppRouteId.home);

  Uri product(String id) => AppCoordinator.manifest.location(
    AppRouteId.product,
    pathParameters: {'id': id},
  );
}

// Wire up:
MaterialApp.router(routerConfig: AppCoordinator())

Rules:

  • Every RouteManifestRoute must have exactly one binding. Layout IDs must not be bound.
  • notFound is required on a standalone registry so unmatched URIs still produce a route. That class mixes RouteNotFound.
  • Hand-written IDs are enums plus RouteIdCodec.enumValues. Generated file-based IDs are class-name strings.

3. Modular Features

Split parsing across RouteModules with RouteModuleBinding. The app coordinator mixes only CoordinatorModular — never also RouteModuleBinding (the two both override parseRouteFromUri).

dart
enum ShopRouteId { layout, home, product }

class ShopModule extends RouteModule<AppRoute>
    with RouteModuleBinding<AppRoute, ShopRouteId> {
  ShopModule(super.coordinator);

  static final manifest = RouteManifest<ShopRouteId>(
    name: 'shop',
    idCodec: RouteIdCodec.enumValues(ShopRouteId.values),
    routes: [
      RouteManifestRoute(
        id: ShopRouteId.home,
        path: '/shop',
        parentId: ShopRouteId.layout,
      ),
      RouteManifestRoute(
        id: ShopRouteId.product,
        path: '/shop/products/:id',
        parentId: ShopRouteId.layout,
      ),
    ],
    layouts: [
      RouteManifestLayout.stack(id: ShopRouteId.layout, path: '/shop'),
    ],
  );

  @override
  late final routeBindings = manifest.bind<AppRoute>(
    bindings: [
      RouteBinding(id: ShopRouteId.home, create: (_) => ShopHomeRoute()),
      RouteBinding(
        id: ShopRouteId.product,
        create: (match) => ProductDetailRoute(id: match.pathParameters['id']!),
      ),
    ],
    // no notFound — unmatched URIs must return null so other modules can claim them
  );

  late final shopStack = NavigationPath<AppRoute>.createWith(
    coordinator: coordinator, // inherited field = root coordinator
    label: 'shop',
  )..bindLayout(ShopLayout.new);

  @override
  List<StackPath> get paths => [shopStack];
}

class AppCoordinator extends Coordinator<AppRoute>
    with CoordinatorModular<AppRoute> {
  @override
  Iterable<RouteModule<AppRoute>> defineModules() => [
    AuthModule(this),
    ShopModule(this),
  ];

  @override
  AppRoute notFoundRoute(Uri uri) => NotFoundRoute(uri: uri);
}

Rules:

  • Module order in defineModules() is matching order. Duplicate module runtime types throw.
  • defineModules() is snapshotted once — return a fixed iterable, not a rebuilt factory.
  • A module binding must omit notFound. Only the root notFoundRoute (or a standalone registry's notFound) handles misses.
  • Use inherited coordinator in NavigationPath.createWith.
  • bindLayout(LayoutClass.new) takes the constructor, not an instance.
  • CoordinatorModular composes every module routeManifestFragment and validates the full graph (cross-module parentId, cycles, ambiguous paths).
  • Do not override parseRouteFromUri on the modular coordinator.

A module that only references a layout declared by another module must override routeManifestFragment instead of a self-contained RouteManifest. See Fragments in ADVANCED.md.

Nested feature groups: Coordinator as Module.


4. Route Definition

dart
class ShopHomeRoute extends AppRoute {
  @override
  Type? get layout => ShopLayout;

  @override
  Uri toUri() => ShopModule.manifest.location(ShopRouteId.home);

  @override
  Widget build(covariant AppCoordinator coordinator, BuildContext context) {
    return ShopHomePage(
      onProductTap: (id) => coordinator.push(ProductDetailRoute(id: id)),
    );
  }
}

class ProductDetailRoute extends AppRoute {
  ProductDetailRoute({required this.id});
  final String id;

  @override
  List<Object?> get props => [id];

  @override
  Type? get layout => ShopLayout;

  @override
  Uri toUri() => ShopModule.manifest.location(
    ShopRouteId.product,
    pathParameters: {'id': id},
  );

  @override
  Widget build(covariant AppCoordinator coordinator, BuildContext context) =>
      ProductDetailPage(id: id);
}

class NotFoundRoute extends AppRoute with RouteNotFound {
  NotFoundRoute(this.uri);
  final Uri uri;

  @override
  Uri toUri() => uri;

  @override
  List<Object?> get props => [uri];

  @override
  Widget build(covariant AppCoordinator coordinator, BuildContext context) =>
      NotFoundPage(uri: uri);
}

Rules:

  • layout / parentLayoutKey is the runtime shell — the RouteLayout Type (default layoutKey is runtimeType).
  • Manifest parentId is the static parent ID (ShopRouteId.layout or 'ShopLayout'). It is not the same value as layout; they must refer to the same shell.
  • Override props for every constructor parameter.
  • Prefer a location helper on the coordinator when one exists (coordinator.location.product(id)).

Redirect-only routes: RedirectRule.


Show full SKILL.md (395 more words)Show less

5. Layout

dart
class ShopLayout extends AppRoute with RouteLayout<AppRoute> {
  @override
  StackPath<AppRoute> resolvePath(covariant AppCoordinator coordinator) =>
      coordinator.getModule<ShopModule>().shopStack;

  @override
  Widget build(covariant AppCoordinator coordinator, BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Shop')),
      body: buildPath(coordinator),
    );
  }
}

Rules:

  • Call buildPath(coordinator) — do not call super.build().
  • resolvePath returns the exact path that was bindLayout-ed.
  • Declare the same layout in the manifest (RouteManifestLayout.stack / .indexed / .branched) and at runtime (bindLayout).
  • Tabs and stateful shells: IndexedStackPath / BranchedStackPath.

6. Navigation

dart
coordinator.push(ProductDetailRoute(id: '42'));
coordinator.navigate(ShopHomeRoute());
coordinator.replace(SettingsRoute());
coordinator.pop();

// Same graph, no RouteTarget instance:
await coordinator.location.product('42').recoverWith(coordinator);
await coordinator.pushUri(ShopModule.manifest.location(
  ShopRouteId.product,
  pathParameters: {'id': '42'},
));

Redirect rules run on every navigation call.

Method choice and URI helpers: NAVIGATION.md.


7. File-Based Routes

When the project already uses zenrouter_file_generator:

dart
// lib/routes/shop/products/[id].dart  →  /shop/products/:id
@ZenRoute()
class ProductIdRoute extends _$ProductIdRoute {
  ProductIdRoute({required super.id});

  @override
  Widget build(covariant AppCoordinator coordinator, BuildContext context) =>
      ProductPage(id: id);
}
FileURL
index.dart/path
about.dart/path/about
[id].dart/path/:id
[...slugs]//path/*
_layout.dartlayout only
(group)/layout group, not a URL segment
shop.products.[id].dart/shop/products/:id (dot nesting)

@ZenLayout(type: LayoutType.stack|indexed|branched) on _layout.dart. Generated AppCoordinator already mixes RouteModuleBinding<AppRoute, String> and exposes AppCoordinator.location / pushProductId(id).


8. File Structure (hand-written)

lib/src/router/
├── coordinator.dart          ← Root Coordinator or Coordinator-as-Module
├── route.dart                ← Base route type (e.g. AppRoute)
├── _public.dart              ← Barrel: public routes + rules
├── rules/
│   ├── auth_required.dart
│   └── force_redirect.dart
└── routes/
    ├── (auth)/               ← Layout group (not a URI segment)
    │   ├── _layout.dart
    │   ├── sign_in.dart      ← /sign-in
    │   └── forgot_password.dart
    ├── (dashboard)/
    │   ├── _layout.dart
    │   ├── _index.dart
    │   └── transactions/
    │       ├── _index.dart   ← /transactions
    │       └── [id].dart     ← /transactions/:id
    │   └── blog/
    │       ├── _layout.dart
    │       └── [...slug].dart ← /blog/...:slug
    └── not_found.dart

Keep the file name, manifest path, and location helper in lockstep. rules/ holds reusable RedirectRules.


9. Naming

Route classes
PatternExampleWhen
<Feature>RouteSignInRouteStandard page
<Feature>DetailRouteTransactionDetailRoute[id] / :id page
<Feature>IndexRouteDashboardIndexRouteIndex / redirect-only
<Feature>TabHomeTabIndexed-stack tab
NotFoundRouteNotFoundRoute404; mix in RouteNotFound
Layout, module, rule, and ID types
PatternExampleWhen
<Feature>LayoutShopLayoutShell
<Feature>ModuleShopModuleRouteModule
<Feature>CoordinatorShopCoordinatorCoordinator-as-Module
<Feature>RouteIdShopRouteIdHand-written manifest IDs (enum)
<Condition>RuleAuthRequiredRuleRedirect / guard rule
URIs and labels

Kebab-case segments. Singular resource details (/transaction/:id). NavigationPath labels: 'auth', 'dashboard', 'shop-products'.


10. Adding a Feature: Checklist

File-based: add the annotated file → build_runner → navigate via generated pushX / location.

Manifest-bound:

  1. Add an ID to the feature enum (or a RouteManifestRoute with the generated class-name string).
  2. Add the pattern (and parentId if it lives under a layout).
  3. Add a RouteBinding that reads pathParameters / restParameters.
  4. Create the route class: layout, toUri() via manifest.location, props, build().
  5. Export from _public.dart if other features navigate to it.
  6. New layout? RouteManifestLayout.* + NavigationPath/IndexedStackPath/BranchedStackPath + bindLayout + RouteLayout class + paths.
  7. New module? RouteModule + RouteModuleBinding, register in defineModules().
  8. Feature group with sub-modules? Coordinator-as-Module.

Common Mistakes

MistakeFix
parseRouteFromUri switch on new workUse RouteModuleBinding
Mixing RouteModuleBinding with CoordinatorModularModular root uses only CoordinatorModular; child modules use RouteModuleBinding
Module binding sets notFoundOmit it so other modules can match
Binding a layout ID, or leaving a route unboundBind every RouteManifestRoute; never bind a layout
toUri() via Uri.parse('/…')manifest.location(id, pathParameters: …)
parentId / layout disagreeManifest parentId and runtime layout must name the same shell
Overriding parseRouteFromUri on a binding or modular coordinatorDon't — the mixin owns it
Forgetting ...super.pathsAlways spread super.paths
File-based: editing routes.zen.dartAdd a source file; regenerate
Parser-era coordinator: rewriting onto a manifest unaskedAdd a switch case instead

© definev, 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

SKILL.md and 3 other files in skills/zenrouter of definev/zenrouter.

  • SKILL.md
  • ADVANCED.md
  • MIXIN.md
  • NAVIGATION.md

Open the folder on GitHubat commit 8c536fc

Compare with similar skills

Zenrouter 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.

Zenrouter compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Zenrouter this skilldefinev/zenrouter102—~4.3kAutomated safety check: PassApache-2.0
Add Flutter Docusaurus Localematthiasn/lotti1.2k—~1.2kAutomated safety check: PassGPL-3.0
Tm Launcher DesignFar-Se/tabame372—~3.1kAutomated safety check: PassMIT
Flutter Initbear2u/my-skills933—~2.5kAutomated safety check: PassNone
Mobile App UI Designceorkm/mobile-app-ui-design403—~2kAutomated safety check: PassNone
Marionette Flutter Drive Appleancodepl/marionette_mcp482—~11kAutomated safety check: PassApache-2.0

Similar skills

  • Add, complete, or audit a locale across a Flutter application's ARB catalogs and a localized Docusaurus manual, including generated localization code, locale selectors, native platform declarations…

    1.2k GitHub stars~1.2k tokensUpdated today
    MobileAuto-check passed
  • Tm Launcher Design

    Far-Se/tabame

    Create or revise Tabame's Flutter launcher designs: frames, search bars, result rows, palettes, typography, and action dialogs.

    372 GitHub stars~3.1k tokensUpdated yesterday
    MobileAuto-check passed
  • Flutter Init

    bear2u/my-skills

    A skill your agent uses when user wants to create a new Flutter project (Todo/Habit/Note/Expense/Custom domain) with Clean Architecture, Riverpod 3.0, Drift, and modern Flutter stack

    933 GitHub stars~2.5k tokensUpdated 3 mo ago
    MobileAuto-check passed
  • Mobile App UI Design

    ceorkm/mobile-app-ui-design

    Design high-quality mobile app UI/UX screens, flows, and components.

    403 GitHub stars~2k tokensUpdated 3 mo ago
    MobileAuto-check passed
  • Marionette Flutter Drive App

    leancodepl/marionette_mcp

    Set up and drive a running Flutter app (debug or profile) with Marionette — an AI agent's hands and eyes for the app.

    482 GitHub stars~11k tokensUpdated 3 days ago
    MobileAuto-check passed
  • Flutter Screenshot

    JustLookAtNow/pt_mate

    Capture and show two Flutter UI screenshots for this project: one landscape/large-screen preview and one portrait/mobile preview, without using Flutter Web.

    503 GitHub stars~511 tokensUpdated 3 days ago
    MobileAuto-check passed

Works with

Categories

Questions about Zenrouter

What does Zenrouter do?

Implement and extend routing with zenrouter's Coordinator, RouteManifest, and RouteBinding APIs. Zenrouter is an agent skill from definev/zenrouter. Implement and extend routing with zenrouter's Coordinator, RouteManifest, and RouteBinding APIs.

When should I use Zenrouter?

Zenrouter fits situations like: nested coordinator; programmatic navigation; coordinatorModular; routeModuleBinding.

How do I install Zenrouter in Claude Code?

Run `npx skills add definev/zenrouter --skill zenrouter -a claude-code`. Or copy the skill folder (skills/zenrouter in definev/zenrouter) into .claude/skills/zenrouter in your project. Claude Code loads it when a task matches its description.

How do I install Zenrouter in Codex?

Run `npx skills add definev/zenrouter --skill zenrouter -a codex`. Or copy the skill folder (skills/zenrouter in definev/zenrouter) into .agents/skills/zenrouter in your project. Codex loads it when a task matches its description.

Can I use Zenrouter 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 definev/zenrouter --skill zenrouter -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/zenrouter, .gemini/skills/zenrouter, .github/skills/zenrouter and .opencode/skills/zenrouter in your project.

What does Zenrouter need to run?

Going by SKILL.md and its folder, Zenrouter needs the command-line tools its instructions call (dart).

Does Zenrouter access the network?

SKILL.md names 1 domain. As links in the text: pub.dev. This is read from the text; nothing was executed.

Is Zenrouter 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 Zenrouter use?

Zenrouter 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 Zenrouter use?

About 4.3k tokens (SKILL.md is roughly 17k 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 Zenrouter?

Skills that share tags, products or a category with Zenrouter: Add Flutter Docusaurus Locale (matthiasn/lotti, 1.2k stars), Tm Launcher Design (Far-Se/tabame, 372 stars), Flutter Init (bear2u/my-skills, 933 stars) and Mobile App UI Design (ceorkm/mobile-app-ui-design, 403 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Zenrouter?

definev (a GitHub user) maintains it in definev/zenrouter, which has 102 GitHub stars. The repository was last updated on October 2, 2026.

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