TanStack Intent: Complete Guide with Real Examples

TanStack Intent ships agent skills inside your npm package. Complete 2026 guide: every CLI command, measured output, and the fixes that actually worked.

Huifer
Huifer
October 22, 202611 min read
Also available in:中文

Written by Huifer, solo developer and maintainer of TanStack Ship. If you build an npm package and want coding agents to use it correctly, this guide is the field manual I wanted before shipping my own skills. I have shipped Agent Skills inside npm packages since 2026, ran @tanstack/intent against this repository on 2026-10-22, counted what it discovered, and wrote down every command and every failure.

Verified sources: TanStack Intent · Intent on GitHub · @tanstack/intent on npm · TanStack Start docs · Cloudflare Workers TypeScript · web.dev INP guide

Last updated: 2026-10-22 · Changelog

TL;DR: TanStack Intent is a CLI and publishing convention that turns an npm package into a source of agent skills that coding agents discover on their own. I ran the CLI against this repository on 2026-10-22: it discovered 11 intent-enabled packages holding 41 skills, and intent load prints a single SKILL.md into the agent context on demand.

Definition: TanStack Intent is a CLI plus a publishing convention that lets an npm package ship Agent Skills, meaning SKILL.md files with frontmatter, which AI coding agents can discover and load on demand.

What TanStack Intent Actually Does

This guide covers the whole CLI: discovery, validation, CI wiring, and the traps I hit. It does not cover authoring skills for one framework beyond the shipped examples.

Intent does three things. It finds packages in your workspace that ship skills, it validates that those skills are well formed, and it prints one skill's guidance into the conversation so an agent can act on it. There is no runtime, no proxy, no server. The distribution channel is the npm registry and the transport is a file.

The three moving parts

The first part is the skill, a SKILL.md file with YAML frontmatter carrying a name, a description that tells an agent when the skill is relevant, and metadata tying it to the package version that shipped it. The second part is the package, an ordinary npm package that includes its skills in the published tarball. The third part is the loader, the @tanstack/intent CLI, which reads installed packages from node_modules and reports what it found. The format integrates with the agent tooling you already run, which is why the CLI enforces the contract.

Why npm is the distribution channel

An agent that already installs your dependency does not need your documentation separately. It already has it. That is the reasoning behind the Agent Skills specification, and it is why Intent ships as a dev dependency. For my template work this matters on Cloudflare Workers, where the runtime bundle is assembled from node_modules and conventions come from the Workers TypeScript docs.

Install and First Run

The CLI runs through npx, so there is nothing to install globally. It must run inside the project, because it resolves the workspace from the current directory.

bash
# Run the discovery command inside the project root
npx @tanstack/intent@latest list

Each row in the output is an installed package that ships at least one skill, with a version and a skill count. This is what the command printed here on 2026-10-22:

PackageVersionSkills
@tanstack/router-core1.171.810 skills
@reduxjs/toolkit2.12.08 skills
@tanstack/start-client-core1.170.67 skills
@tanstack/devtools0.12.54 skills
@tanstack/react-start1.168.183 skills
@tanstack/devtools-event-client0.5.03 skills
dotenv17.4.22 skills
@tanstack/devtools-vite0.8.11 skill
@tanstack/router-plugin1.168.131 skill
@tanstack/start-server-core1.169.81 skill
@tanstack/virtual-file-routes1.162.01 skill

Reading the output

Three things stand out. Discovery works through normal npm resolution, so a package that ships skills is found without extra configuration. Skill counts vary widely, showing how opinionated each maintainer is about agent guidance. Versions matter too, because a skill describing an old API is worse than none.

Outside a project the same command prints No intent-enabled packages found. plus a notice that a future version will require an explicit intent.skills allowlist. That notice matters most if you ship skills to strangers.

Across multiple runs of intent list here, over 5 months of use, the discovered set stayed the same, so discovery is stable even while the CLI version moves.

Every Command, in the Order I Use Them

The CLI exposes fifteen commands: list, exclude, load, meta, repair, validate, install, hooks, maintainer, review, stale, edit-package-json, setup, setup-github-actions, and help. I use six weekly.

load — pull one skill into the context

load is the command an agent uses. The syntax is package#skill, and the output is the raw SKILL.md including its frontmatter:

bash
# Load the dotenv skill into the current agent context
npx @tanstack/intent@latest load dotenv#dotenv

The skill text arrives with its own frontmatter, so the agent sees name, description, license, and source metadata. It is a file read, not a summary, so the agent follows it literally.

meta — the authoring meta-skills

intent meta lists four meta-skills for library maintainers: domain-discovery, generate-skill, skill-staleness-check, and tree-generator. They are instructions for an agent helping you write skills, which avoids asking a model to invent an API surface.

maintainer — setup, add, remove, status, sync, review, check

This is the command for a package that ships its own skills. Set up the planning records, add a skill for a new domain, then sync the tree and check it in CI.

bash
# Initialize planning records, register existing skills, install CI
npx @tanstack/intent@latest maintainer setup

# Create a skill skeleton for a domain
npx @tanstack/intent@latest maintainer add my-skill --domain my-domain --description "What it does"

# Align the skill tree with SKILL.md frontmatter
npx @tanstack/intent@latest maintainer sync

setup writes four things: skill_tree.yaml, domain_map.yaml, skill_spec.md, and a .github/workflows/check-skills.yml file when one does not exist. It also registers any SKILL.md under skills/ that is not recorded. check is the CI gate, and it fails the build on authoring issues, stale generated files, or pending reviews.

validate, stale, review — keeping skills honest

These three are the difference between a skill and a stale README. validate checks frontmatter and can rewrite fixable issues with --fix, or fail the build with --check. It also takes --set-version <version> to stamp metadata.library_version on matched skills.

stale reports skills whose sources have moved on, with --json for machine output and --github-review to write review PR files. review compares first-party skills against Git changes with --base <ref>.

Shipping Skills From Your Own Package

If you maintain a package, this is the part that matters. Skills ship inside the npm tarball, so the files array in package.json must include the skills directory:

json
{
  "name": "@tanstack/react-start",
  "version": "1.168.18",
  "files": ["dist", "src", "skills", "bin", "!skills/_artifacts"]
}

That is the real files array from the published @tanstack/react-start package on 2026-10-22. The skills entry is what makes the skills visible to intent list.

The SKILL.md contract

A framework skill in that package carries more frontmatter than a simple one. The fields I verified in the shipped SKILL.md files are name, description, type, library, library_version, framework, requires, and sources. The requires and sources fields let a maintainer express dependencies between skills and point at the code a skill describes. The CLI labels each skill as core, framework, or sub-skill.

The Vite plugin ordering trap

The @tanstack/devtools-vite skill documents that its plugin must be the first plugin in the Vite config, that it supports Vite 6 and Vite 7 only, and that it exposes an inspect hotkey, console piping levels, a server event bus with configurable port and host, and an editor integration hook through launch-editor. Every one of those details is in the skill, and none are in my memory of the plugin.

What Broke Along the Way

Nothing here is a complaint about the tool. It is the list of things that stopped me shipping skills in a day, in order.

The version gap between npm and my lockfile

Before: my package.json pinned @tanstack/intent at ^0.0.41, added in commit id 572fb7d on 2026-05-16, while npm latest had moved to 0.5.6.

After: I run the CLI through npx @tanstack/intent@latest for inspection and keep the pinned version for anything scripted. The trade-off is deliberate: pinning a development tool while the package stays on an older release is what creates confusion.

Verification: I compared npm view @tanstack/intent version with the installed version on 2026-10-22 and read the 0.5.6 help output for every command above.

The allowlist notice

Before: I expected intent list to be a stable contract I could build on.

After: the CLI told me a future version will require an explicit intent.skills allowlist. I added the allowlist entry to package.json that same session, which moved the tool from something I was testing to something I relied on.

When to Use Intent, and When Not To

Intent is for maintainers of packages that agents install and then need to use correctly. If you write an application rather than a library, the economics change: one repository, one CLAUDE.md at the root, no version skew to defend against.

My own decision rule: ship skills when your package has more than one consumer shape, when the API surface has breaking changes between versions, or when your guidance depends on setup steps a developer would otherwise skip.

A checklist before you publish

  • Confirm skills appears in the files array of package.json.
  • Run intent validate --check in CI and fail the build on errors.
  • Run intent maintainer check --base <ref> so stale generated files block merges.
  • Stamp metadata.library_version with --set-version at release time.
  • Verify the published tarball contains the skills directory, not only the local tree.

That last line is the one people skip. A skill in your working copy but not in the published tarball is invisible to every agent that installs the package. I checked the tarball, not the tree.

Limitations of This Guide

Everything here was measured on 2026-10-22, in this repository, on one machine, against npm registry production data for the trailing 30 days. I have not tested on Windows, and I have not run intent install or intent hooks in a shared CI matrix, so treat those two commands as documented rather than verified. I ran no benchmark of agent success rate with and without skills, so I cannot tell you how much those 41 skills improve an outcome.

Disclosure: I build and sell TanStack Ship, the product linked below, so there is a material connection between me and that link. Every measurement above is first-party CLI output I reproduced myself; the npm download counters are registry production data.

FAQ

Does TanStack Intent replace my README?

No, and it should not. A README explains what a package does to a human reading it in a browser. A skill explains how to use that package correctly to an agent that already decided it needs the package. My packages keep both, the skill focused on details that break between versions.

Do I need to publish to npm for skills to work?

For the discovery path, yes, because discovery reads installed packages from node_modules. During development I load a skill from a path in the working tree. Publishing a skill where an agent never installs from does not work, because nothing triggers the lookup.

Which agents support Intent?

The skill format is plain markdown with frontmatter, and the intent install and intent hooks commands write loading guidance into agent configuration for supported agents, including Copilot, Claude, and Codex. The mechanism is a convention rather than a proprietary API, so an agent reading a SKILL.md can use it without the CLI.

Is @tanstack/intent stable enough to depend on?

Treat it as a moving target during 2026. The CLI gave me 0.5.6 as latest on 2026-10-22, it warns that a future version will require an explicit allowlist, and my own repository still pins an older release. Pin it if you script against it, and re-read the help output before a release that changes commands.

What is the difference between a skill and a hook?

A skill is guidance the agent reads when it decides the guidance is relevant. A hook is a mechanism the CLI installs into agent configuration that surfaces or enforces loading. Skills answer what to know; hooks answer when to surface it. You can use skills without hooks.

Related reading: Tanstack Intent Production Guide 2026 · Tanstack Query V5 Migration Complete Guide 2026 · Tanstack Hotkeys Complete Guide 2026

Conclusion

TanStack Intent is a small tool with a specific promise: if your npm package ships skills, an agent that installs your package can find and load them without a human copying instructions. The CLI gives you discovery, validation, staleness checks, and CI wiring, and the format is markdown with frontmatter rather than something exotic. The gaps are narrow and named: a version gap between the published CLI and my pinned dependency, an allowlist that will likely become mandatory, and flags I read but did not exercise under load. If you ship a library and want agents to use it correctly, the next step is cheap: add the skills directory to your files array, run intent validate --check, and publish. The TanStack Ship templates ship with skills wired into build and CI, and the SaaS boilerplate comparison lists which starters include agent-ready setup.

On this site the post is served with a canonical URL and BlogPosting JSON-LD, so the metadata carries into search results and AI answers.

Further reading