Tool Platform is a browser-first, plugin-oriented tool platform. Every tool is an independent workspace plugin package: tools register through manifests and are connected to shared category, search, dynamic route, and runtime management systems, all governed at build time by the registry generator.
The repository includes the Next.js web app, pnpm workspace, manifest-driven tool registration with build-time governance, dynamic tool pages, category surfaces, a homepage-first search experience, and runtime packages for local tool execution.
- Manifest-driven plugin directory: every tool provides a bilingual
manifest.ts(name/descriptionas{ zh, en }) +app.tsx. - Automatic registration and governance:
pnpm generate:toolsscanstools/*, validates manifests via the TypeScript AST (bilingual completeness, category/runtime/permission allowlists, and runtime declarations enforced against actual runtime SDK usage), and generates the registry, client loaders, guide aggregate, and per-tool READMEs. - Dynamic routes: the web app loads tool apps through
/tools/[slug]and optional nested subpaths such as/tools/[slug]/schema. - Categories and search: tool manifests contribute
category,subCategory,tags, anddescriptionmetadata. - Runtime foundation: shared contracts and runtime packages for simple, worker, wasm, ai, sandbox, and realtime tools;
runtimedeclarations are enforced contracts, not decoration. - Browser SDK: shared helpers for clipboard, downloads, file opening, OPFS cache, toast feedback, runtime lifecycle, Worker, WASM, AI, and iframe sandbox capabilities.
- Bilingual content system: manifests embed zh/en metadata, guides live in each tool's
guide.json(Chinese), and platform chrome copy flows through next-intl.
- Monorepo: pnpm workspace + Turborepo
- Web app: Next.js 15 + React 19 + TypeScript
- Styling: Tailwind CSS 4
- Tool registry: Node.js scripts + TypeScript manifests
- Browser runtimes: Web Worker, WASM, OPFS, iframe sandbox, and local AI runtime foundations
Use Node.js 20+ and pnpm 10.x. The repository pins pnpm@10.28.1 in package.json.
corepack enable
pnpm install
pnpm devThen open:
http://localhost:3000
pnpm dev runs pnpm generate:tools first, then starts workspace development tasks through Turborepo.
Production-style container run:
docker compose up --buildDevelopment container with hot reload:
docker compose -f docker-compose.dev.yml up --buildBoth configurations publish container port 3000 to ${TOOL_PLATFORM_PORT:-3000} on the host.
| Command | Description |
|---|---|
pnpm dev |
Generate the tool registry and start development servers |
pnpm build |
Generate the tool registry and build all workspaces |
pnpm lint |
Generate the tool registry and run type/lint checks |
pnpm test |
Generate the tool registry and run tests |
pnpm generate:tools |
Scan tools/*, validate governance rules, and generate registry, guides, READMEs, and dependency manifests |
pnpm create-tool |
Create a local tool skeleton interactively or through flags |
Create a local tool non-interactively:
pnpm create-tool json-diff --name "JSON Diff" --category data-tools --runtime simpletool-platform/
|-- apps/
| `-- web/ # Next.js web app, homepage search, tool pages, and category pages
|-- packages/
| |-- tool-contracts/ # Single source of truth: ToolManifest, ToolRuntime, category/runtime allowlists
| |-- tool-sdk/ # Pure-data registry, categories, search (no tool package dependencies)
| |-- tool-loaders/ # Generated lazy loader map + all tool dependencies
| |-- tool-browser-sdk/ # Browser SDK for tool app implementations
| |-- runtime/ # Tool lifecycle management
| |-- worker-runtime/ # Worker RPC and worker runtime helpers
| |-- wasm-runtime/ # WASM loading, preloading, and cache helpers
| |-- ai-runtime/ # AI model provider/runtime abstractions
| |-- sandbox-runtime/ # iframe sandbox document and client helpers
| `-- storage/ # OPFS file read/write capabilities
|-- tools/
| `-- <tool-id>/ # Individual tool plugin
|-- scripts/
| |-- create-tool/ # Tool skeleton generator
| `-- generate-tool-registry.mjs
`-- docs/ # Architecture and UI/UX design documents
tools/<tool-id>/{manifest.ts, app.tsx, guide.json?}
| pnpm generate:tools (AST validation + generation)
v
packages/tool-sdk/src/generated/manifests.ts # pure-data registry (no tool imports)
packages/tool-sdk/src/generated/guides.ts # guide aggregate
packages/tool-loaders/src/generated/client-loaders.ts # lazy loaders + tool deps
tools/*/README.md # generated docs
| apps/web
v
Home (discovery + search) / category pages /tools/[slug]/[[...segments]]
|
v
ToolMicroFrontendHost (Suspense + ErrorBoundary, hands the tool a localized manifest)
ToolMicroFrontendHost is the single host interface used by tool pages. It resolves the lazy loader from tool-loaders, resolves the bilingual manifest to a LocalizedToolManifest for the active locale, and passes it to the tool component, so tools can render {manifest.name} directly without locale branching.
Every tool package contains a bilingual manifest, a client component, and an optional Chinese guide:
tools/json-formatter/
|-- package.json
|-- manifest.ts
|-- guide.json # optional: Chinese usage guide (intro/steps/examples)
|-- app.tsx
`-- README.md # generated artifact, do not edit by hand
package.json exports both manifest and app:
{
"exports": {
"./manifest": "./manifest.ts",
"./app": "./app.tsx"
}
}Manifest example (name/description must provide both zh and en; the generator enforces this):
import type { ToolManifest } from "@tool-platform/tool-contracts";
const manifest: ToolManifest = {
id: "json-formatter",
name: {
zh: "JSON 格式化工具",
en: "JSON Formatter"
},
description: {
zh: "格式化、压缩并校验 JSON 文本,面向开发工作流。",
en: "Format, minify, and validate JSON text for developer workflows."
},
category: "data-tools",
subCategory: "json",
tags: ["json", "formatter", "validator"],
icon: "braces",
runtime: "simple",
featured: true
};
export default manifest;runtime is a contract: tools declaring worker/wasm/sandbox/ai must actually use the matching runtime SDK (the generator validates this by parsing tool sources), otherwise registration fails; simple/realtime tools must not secretly use those SDKs either.
Single-page tools can render directly in app.tsx; multi-page tools can branch on segments. The component receives a manifest already localized for the active locale (LocalizedToolManifest), so {manifest.name} just works:
"use client";
import type { ToolAppProps } from "@tool-platform/tool-contracts";
export default function JsonFormatterTool({ manifest }: ToolAppProps) {
return (
<section className="tool-panel">
<h2>{manifest.name}</h2>
</section>
);
}- Create a local tool skeleton:
pnpm create-tool my-tool --name "My Tool" --category developer-tools --runtime simple-
Edit
tools/<tool-id>/manifest.tswith accurate bilingual names and descriptions, tags, icon, and runtime; add aguide.json({ intro, steps, examples }) for the Chinese usage guide. -
Implement the input, processing, and output UI in
tools/<tool-id>/app.tsx. -
Regenerate the registry (also enforces governance rules and regenerates the guide aggregate and READMEs):
pnpm generate:tools- Start the dev server and open
/tools/<tool-id>to verify the page.
Tool categories are defined in packages/tool-contracts/src/index.ts and packages/tool-sdk/src/categories.ts. Manifest category values must use these IDs:
ai-tools, developer-tools, ops-tools, security-tools, file-tools, image-tools, media-tools, text-tools, data-tools, office-tools, design-tools, seo-tools, webmaster-tools, learning-tools, calculator-tools, social-tools, ecommerce-tools, productivity-tools, entertainment-tools, discovery-tools
Supported runtime types:
simple, worker, wasm, ai, sandbox, realtime
| Runtime | Use case |
|---|---|
simple |
Lightweight text, formatting, encoding, and calculation tools |
worker |
CPU-heavy, file parsing, or long-running work that should not block the main thread |
wasm |
Reusing high-performance Rust/C/C++ logic |
ai |
Local or remote model inference, embeddings, and streaming chat |
sandbox |
Isolated execution for untrusted HTML/script scenarios |
realtime |
WebSocket, streaming logs, real-time collaboration, or persistent sessions |
- Keep tool plugins independent; do not put tool-specific business logic in
apps/web. manifest.idmust match the tool directory name;name/descriptionmust provide both zh and en (generator-enforced).- Declared
runtimemust match actual runtime SDK usage (AST-validated by the generator); do not use undeclared runtime APIs. description,tags, andsubCategoryparticipate in search and should match terms users would search for.- Write the Chinese usage guide in
guide.json; the EN side falls back to the platform template until translations land. - Prefer Worker, WASM, or dedicated runtime packages for heavy computation or large-file processing.
- Prefer OPFS capabilities exposed by
tool-browser-sdkwhen temporary persistence is needed. - Run
pnpm generate:toolsafter adding, deleting, or renaming tools; CI enforces zero drift on generated artifacts (registry, guide aggregate, READMEs, dependency manifests) withgit diff --exit-code.
Before submitting changes, run at least:
pnpm lint
pnpm testFor package-scoped checks, use pnpm filters:
pnpm --filter @tool-platform/runtime test
pnpm --filter @tool-platform/web lintThis repository is maintained as an open source project:
- LICENSE: MIT license.
- CONTRIBUTING.md: local development, adding tools, required checks, and PR expectations.
- SECURITY.md: vulnerability disclosure, security scope, and sensitive data handling principles.
- PRIVACY.md: local-first data processing boundaries, browser permissions, and remote-call disclosure.
- SUPPORT.md: support expectations and security reporting entry points.
- CODE_OF_CONDUCT.md: community code of conduct.
- CHANGELOG.md: change history.
- ROADMAP.md: project phases and future direction.
GitHub Actions runs generation, lint, test, and build checks on pushes and pull requests. Issue templates, the pull request template, and CODEOWNERS live under .github.