A minimal Next.js 16 starter that calls the Pipelex API via the mthds SDK to run AI methods (.mthds bundles) from a TypeScript app.
It ships three demo pipelines, presented as tabs:
- Text entities (
methods/hello) — extracts{ people, orgs, dates }from pasted text. - PDF summary (
methods/summarize-pdf) — uploads a PDF in the browser and returns a structured{ title, docType, keyPoints }summary from a cheap OpenAI model. - Image generation (
methods/generate-image) — turns a text prompt into an image withgpt-image-1-mini.
- Next.js 16 (App Router) + React 19 + TypeScript 5 (strict)
- Tailwind CSS 3
- Vitest 4 + Testing Library (happy-dom)
- ESLint 9 + Prettier 3, Husky + lint-staged
mthdsSDK for Pipelex API calls
- Node.js 18+
- Access to a Pipelex API server. You have two options:
- Hosted — currently in private beta. Join the waitlist at go.pipelex.com/waitlist. Once you have access, get an API key at app.pipelex.com and point
PIPELEX_API_URLathttps://api.pipelex.com(the default). - Self-hosted — the Pipelex API is open source at github.com/Pipelex/pipelex-api. Run it locally or on your own infra and point
PIPELEX_API_URLat your instance (e.g.http://localhost:8000).
- Hosted — currently in private beta. Join the waitlist at go.pipelex.com/waitlist. Once you have access, get an API key at app.pipelex.com and point
cp .env.example .env.local
# edit .env.local and set PIPELEX_API_KEY
make install
make devOpen http://localhost:3000 and try the three example tabs.
methods/
hello/main.mthds # text → { people, orgs, dates }
summarize-pdf/main.mthds # PDF Document → { title, docType, keyPoints }
generate-image/main.mthds # text prompt → generated Image
public/sample-invoice.pdf # sample PDF, so the PDF example works out of the box
src/
app/ # Next.js App Router (layout, page, globals.css)
actions/ # 'use server' Server Actions — one per pipeline
lib/
pipelexClient.ts # MthdsApiClient singleton
loadBundle.ts # reads the .mthds bundles from disk
errors.ts # classifyPipelineError + PipelineError model
fileEncoding.ts # data-URL validation + Document input envelope
clientFile.ts # browser File → base64 data URL
components/ # ExampleTabs + per-example form/result components
types/ # concept types + parseXxx() narrowers
- The browser submits to a Server Action (
runHelloPipeline,runSummarizePdfPipeline, orrunGenerateImagePipeline). - The Server Action reads the
.mthdsbundle from disk and callsMthdsApiClient.executePipeline()with the bundle TOML + inputs. - The Pipelex API runs the pipe and returns loosely-typed output.
- A
parseXxx()narrower insrc/types/validates the output into a typed shape. - The result is rendered, or a classified
PipelineErroris shown by<ErrorDisplay>.
Text inputs are plain strings. File inputs (the PDF example) go through one extra step:
- The browser reads the chosen
Fileinto a base64 data URL withfileToDataUrl(src/lib/clientFile.ts).Fileobjects are not serializable across the server boundary — the Server Action only ever receives the resultingstring. - The Server Action validates the data URL (
validateDataUrl) and wraps it in a PipelexDocumentenvelope (buildDocumentInput→{ concept: "Document", content: { url, filename, mime_type } }). - The Pipelex API decodes the data URL server-side — the app never hosts the file itself.
Image outputs (the image example) come back as a URL — a storage URL or a base64 data URL — which renders directly in an <img>.
- Add
methods/<name>/main.mthds(the/mthds-buildskill from the mthds-plugins marketplace can generate one). - Add a loader in
src/lib/loadBundle.ts, a type +parseXxx()narrower insrc/types/, and a Server Action insrc/actions/. - Wire it from a component. The three existing examples are the canonical patterns to copy.
| Target | Purpose |
|---|---|
make dev |
Start the Next.js dev server |
make build |
Production build |
make lint |
ESLint |
make format |
Prettier write |
make format-check |
Prettier check (CI) |
make typecheck |
tsc --noEmit |
make test |
Vitest single pass (unit tests, no API call) |
make agent-test |
Vitest, silent on success (for AI agents) |
make test-e2e |
Playwright e2e — hits the real Pipelex API, needs a valid key |
make test-e2e-ui |
Same, with the Playwright UI runner |
make check |
lint + format-check + typecheck |
make all |
check + test + build (does not run e2e — see test-e2e) |
make use-local |
Pack & install sibling ../mthds-js into node_modules (alias: ul) |
make use-npm |
Restore the npm-published mthds package (alias: un) |
make test-e2e runs Playwright specs that open the dev server and exercise each of the three example tabs end-to-end — entity extraction, PDF summary, and image generation — asserting the expected output for each. The specs hit the live Pipelex API using PIPELEX_API_KEY from .env.local, so:
- It costs an LLM call per run.
- It is intentionally excluded from
make all. - First-time setup needs the browser binary:
npx playwright install chromium.
If you have the mthds-js repo checked out as a sibling directory (../mthds-js) and want this app to use it instead of the published npm package:
make use-local # builds ../mthds-js, packs it with `npm pack`, installs the tarball into node_modules/mthds
make use-npm # restores the npm versionAliases: make ul / make un. Re-run make use-local after every SDK edit — the tarball is a snapshot, not a live link. We use a tarball install rather than a symlink because Next.js 16's Turbopack does not follow symlinked workspace packages (Module not found: Can't resolve 'mthds').
| Variable | Purpose | Default |
|---|---|---|
PIPELEX_API_URL |
Pipelex API base URL — hosted (https://api.pipelex.com) or your own self-hosted instance |
https://api.pipelex.com |
PIPELEX_API_KEY |
Bearer token used by the SDK | (required at runtime) |
This project is licensed under the MIT license. Runtime dependencies are distributed under their own licenses via npm.