fern
CLAUDE.md3.8k starsChanged 11 months agoApache-2.0View on GitHub
This repository uses DevBox for reproducible development environments with exact version pinning. DevBox is based on Nix and provides cross-platform support (Mac, Linux, Windows via WSL). Quick Start with DevBox: DevBox automatically provides: Node.js 22, pnpm 9.4.0, Go 1.23, Python 3.10, Poetry 1.8, JDK 17, buf 1.50.0, and git-lfs. All versions are pinned in devbox.json to match CI. Manual .NET Installation (Required for C# generator development): DevBox cannot pin multiple .NET SDK versions simultaneously, so .NET must be installed separately.…
- Pipes a download into a shell
- Installs packages
We split this CLAUDE.md into the rules it gives an agent
31 rules. About 0 are common, 7 are distinctive, and 24 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
24
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 82
Dependency Management: Run pnpm check:knip to check for unused dependencies (or pnpm depcheck which delegates to knip via turbo)
- Distinctive: line 113
IR-Centric: All API definitions convert to canonical IR format for consistent generator behavior
- Very specific: line 122
When users run fern generate --group <group-name> in production:
- Very specific: line 131
IR Migration: If needed, migrates IR backward to match generator's expected version using /packages/cli/generation/ir-migrations
- Distinctive: line 158
Run seed test to reproduce issue
- Distinctive: line 169
When you need to change a generator default or behavior in a way that is not backwards compatible:
- Very specific: line 190
API Schema: Update /fern/apis/<definition>/ → Run generator command (check generators.yml in each API folder)
- Very specific: line 194
Add an entry to packages/ir-sdk/fern/apis/ir-types-latest/changelog/CHANGELOG.md (hand-edited.
- Very specific: line 195
Do not edit packages/cli/cli/versions.yml irVersion for minor/patch — that field tracks the IR major and only changes during major bumps
- Very specific: line 197
CLI Versioning: Add a CLI changelog entry under packages/cli/cli/changes/unreleased/ (drives CLI semver only — see packages/cli/CLAUDE.md)
- Very specific: line 200
IR Migrations: Only required for major IR bumps — add under /packages/cli/generation/ir-migrations/
- Very specific: line 229
Testing: Always run pnpm test:ete for end-to-end validation after CLI changes
- Distinctive: line 230
Monorepo: Use Turbo filters for focused builds/tests on specific packages
- Very specific: line 237
Never use
any: If the type is truly unknown, use unknown and narrow it with type guards. - Very specific: line 245
Never use
@ts-ignore: If you must suppress an error, use @ts-expect-error with a comment explaining why, and only as a last resort. - Very specific: line 247
Never use loose types like
object,{}, orFunction: Use specific object shapes, Record<K, V>, or typed function signatures like () => … - Very specific: line 284
Never use
.then()chains whenasync/awaitis available: Prefer linear async code over nested callbacks or promise chains. - Very specific: line 294
Never throw strings or plain objects: Always throw Error instances (or subclasses) to preserve stack traces.
- Very specific: line 300
Never mutate function parameters: Create new objects/arrays instead.
- Very specific: line 302
Prefer
constoverlet: Only use let when reassignment is actually necessary. - Very specific: line 310
Never use
require()in TypeScript: Use ES module import syntax. - Very specific: line 328
Validation: Run pnpm compile to check for issues.
- Very specific: line 334
New fixtures: Create /seed/<generator>/<fixture>/ directory → Add seed.yml config → Run pnpm seed:build → Run pnpm test:update and pnpm …
- Distinctive: line 340
When creating pull requests in this repository:
- Very specific: line 342
PR Title: Must follow semantic commit message rules enforced by CI (.github/workflows/lint-pr-title.yml).
- Distinctive: line 350
Assignee: Always assign the person who prompted you to create the PR as the assignee
- Very specific: line 351
Description: Follow the PR template in .github/pull_request_template.md
- Distinctive: line 352
Testing: Ensure all tests pass before marking PR as ready for review
- Very specific: line 392
After writing the ADR, number it by finding the highest existing docs/adr/NNNN-*.md and incrementing by one.
- Very specific: line 399
Generator failures: Check docker ps → Rebuild image → Check container logs
- Very specific: line 402
Performance: Use Turbo filters | pnpm clean then rebuild | Check Docker limits
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Development Environment Setup
This repository uses DevBox for reproducible development environments with exact version pinning. DevBox is based on Nix and provides cross-platform support (Mac, Linux, Windows via WSL).
Quick Start with DevBox:
# Install DevBox (if not already installed)
curl -fsSL https://get.jetify.com/devbox | bash
# Enter the development environment (installs all dependencies automatically)
devbox shellDevBox automatically provides: Node.js 22, pnpm 9.4.0, Go 1.23, Python 3.10, Poetry 1.8, JDK 17, buf 1.50.0, and git-lfs. All versions are pinned in devbox.json to match CI.
Manual .NET Installation (Required for C# generator development):
DevBox cannot pin multiple .NET SDK versions simultaneously, so .NET must be installed separately. The C# generators require:
- .NET 10 (latest)
- .NET 9 (test TFM)
We provide a setup script that helps:
bash scripts/setup-dotnet.shThis script checks for required .NET versions and can automatically install them using official Microsoft installation scripts, or provide links to the official guides. When you run devbox shell, the setup script runs automatically and the .NET installation is added to your PATH.
Alternatively, follow Microsoft .NET Installation Guide for your platform (macOS, Linux, Windows) and install to $HOME/.dotnet.
Available DevBox Scripts:
devbox run install # Run pnpm install
devbox run compile # Compile all packages
devbox run test # Run tests
devbox run lint # Run lintingDevelopment Commands
Package Manager: This project uses pnpm (version 9.4.0+) exclusively. Node.js 18+ required.
Important: Commands from the root package.json can be run directly with pnpm <command>. However, when running commands defined in subfolder package.json files, always use pnpm turbo run <command> so that Turbo can execute dependent tasks first (e.g., compilation before testing).
Common Commands (from root):
# Initial setup
pnpm install # Install dependencies
# Building
pnpm compile # Compile all packages (production build)
pnpm compile:debug # Compile with debug info
pnpm clean # Clean all build outputs
# Testing
pnpm test # Run all tests (excludes end-to-end tests)
pnpm test:debug # Run tests with debug info
pnpm test:update # Update test snapshots
pnpm test:ete # Run end-to-end tests (slower, requires CLI build)
# Linting & Formatting
pnpm lint:eslint # Run ESLint
pnpm lint:eslint:fix # Fix ESLint issues
pnpm format # Check formatting with Biome
pnpm format:fix # Fix formatting issues
# Fern CLI (for testing)
pnpm fern:build # Build production CLI
pnpm fern:local # Run local development CLI
pnpm fern # Run local CLI directly
# Seed (generator testing)
pnpm seed:build # Build seed CLI for generator testingRunning Individual Package Commands: For commands in subfolder packages, use pnpm turbo run <command> --filter @fern-api/cli (e.g., pnpm turbo run test --filter @fern-api/cli)
Dependency Management: Run pnpm check:knip to check for unused dependencies (or pnpm depcheck which delegates to knip via turbo)
Architecture Overview
Fern is a CLI tool for API-first development that transforms API definitions into SDKs and documentation. The architecture has three main layers:
1. CLI Layer (/packages/cli/)
- Entry Point:
packages/cli/cli/src/cli.ts- Main yargs-based CLI - Key Components:
- Configuration management (
fern.config.json,generators.yml) - Project/workspace loading and validation
- Command orchestration (
generate,check,init,mock, etc.) - Logging and error handling infrastructure
- Configuration management (
2. Core Processing (/packages/)
- Workspace Management: Loads and validates API workspaces from multiple formats
- IR (Intermediate Representation): Central data structure (
/ir-sdk/) consumed by all generators - Import/Export: Converts external formats (OpenAPI, AsyncAPI, gRPC) to Fern IR
- Utilities: Core libraries for file system, logging, path handling, etc.
3. Generator Layer (/generators/)
Language-specific generators that consume IR and produce outputs:
- Pattern: Each language has
base/,ast/,model/,sdk/, sometimesserver/ - Supported: TypeScript, Python, Java, Go, C#, Ruby, PHP, Rust, Swift
- Special: OpenAPI export
4. Testing (/seed/)
Comprehensive generator testing with Docker-based fixtures across all supported languages.
Key Architectural Patterns
- IR-Centric: All API definitions convert to canonical IR format for consistent generator behavior
- Plugin Architecture: Generators are Docker-containerized plugins implementing
AbstractGeneratorCli - Workspace-Based: Projects support multiple API workspaces with different configurations
- Turbo Monorepo: Uses pnpm workspaces + Turbo for builds and caching
Core Workflows
Production SDK Generation Flow
When users run fern generate --group <group-name> in production:
- CLI Version Check: Fern CLI checks
fern.config.jsonfor required version and auto-downloads/installs if needed - Configuration Discovery: CLI locates
generators.ymlfile(s) in the fern directory structure:- Single API:
fern/generators.yml - Multiple APIs:
fern/apis/<api-name>/generators.yml(separate configs per API)
- Single API:
- Generator Selection: Uses
--groupparameter ordefault-groupfield to determine which generator group to run - IR Generation: Creates Fern IR file containing all information needed for generation (always latest IR version)
- Version Compatibility: Checks generator version (e.g.,
typescript-node-sdk:2.6.3) against required IR version (e.g.,irVersion: 58) using/generators/<lang>/sdk/versions.yml - IR Migration: If needed, migrates IR backward to match generator's expected version using
/packages/cli/generation/ir-migrations - Generation Execution:
- Local:
--localflag downloads Docker image and runs generation locally - Remote: Uses Fiddle service for server-side generation (being deprecated)
- Local:
- Output Delivery: Based on
generators.ymloutput configuration:- Package registries: npm, PyPI, Maven, NuGet, RubyGems
- GitHub: release/pull-request/push modes
- Local filesystem: saves to specified directory
Seed Testing (Development)
Seed validates generator changes against test fixtures. Essential for bug fixes and feature development.
Structure: /test-definitions/ (inputs) → /packages/seed/ (CLI) → /seed/<generator>/<fixture>/ (outputs)
Setup: pnpm install && pnpm compile && pnpm seed:build
Commands:
# Test predefined fixture
pnpm seed test --generator python-sdk --fixture file-download --skip-scripts
# Test custom project
pnpm seed run --generator go-sdk --path /path/to/project --skip-scriptsDevelopment Cycle:
- Run seed test to reproduce issue
- Modify generator code
- Re-run seed test (use
git diffto see output changes) - Repeat until fixed
Output: Seed test overwrites /seed/<generator>/<fixture>/, seed run writes to temp directory
Breaking Changes Policy (Generators)
Generators MUST NOT ship breaking changes to existing users without a migration path. Autorelease cannot succeed if a generator silently changes default behavior, and on-call will page.
When you need to change a generator default or behavior in a way that is not backwards compatible:
- Gate the new behavior behind a config flag and keep the old behavior as the default. Users opt in to the new behavior by setting the flag.
- When you are ready to flip the default (major version bump of the generator), add a generator migration under
packages/generator-migrations/src/generators/<generator>/migrations/<next-major>.0.0.ts. The migration must set the old value for users who had not explicitly configured the field, so their existinggenerators.ymlcontinues to produce the same output. - Register the migration in the generator's
migrations/index.tsand publish@fern-api/generator-migrations. Migrations run automatically viafern generator upgrade --include-major.
See packages/generator-migrations/src/generators/typescript/migrations/3.0.0.ts for a reference example (switching TypeScript SDK defaults from yarn/jest to pnpm/vitest). See packages/generator-migrations/README.md for the full authoring guide.
Checklist for any generator-defaults PR:
- Is the new behavior gated so existing users are unaffected until they opt in or a major version lands?
- If this is the major version flip, is there a corresponding migration file under
packages/generator-migrations/? - Is the migration registered in
src/generators/<generator>/migrations/index.ts? - Are there tests for the migration (see
packages/generator-migrations/src/__test__/)?
Skipping this process breaks autorelease for every customer pinned to the old major and will cause an on-call incident.
Feature Addition Workflow (Generated Code)
Multi-stage process: API Schema → IR Updates → Generator Updates → Release
Stages:
- API Schema: Update
/fern/apis/<definition>/→ Run generator command (checkgenerators.ymlin each API folder) - IR Updates: Modify
/packages/ir-sdk/fern/apis/ir-types-latest/definition/→pnpm ir:generate - IR Versioning (REQUIRED for any change to
ir-types-latest):- Bump
packages/ir-sdk/fern/apis/ir-types-latest/VERSION(minor for additive/optional fields, patch for non-schema, major only as a separate batched PR) - Add an entry to
packages/ir-sdk/fern/apis/ir-types-latest/changelog/CHANGELOG.md(hand-edited; nochanges/unreleased/for IR) - Do not edit
packages/cli/cli/versions.ymlirVersionfor minor/patch — that field tracks the IR major and only changes during major bumps - See
packages/ir-sdk/CLAUDE.mdfor the full checklist
- Bump
- CLI Versioning: Add a CLI changelog entry under
packages/cli/cli/changes/unreleased/(drives CLI semver only — seepackages/cli/CLAUDE.md) - Compile:
pnpm compileand fix breaking changes (common:switchstatements need new cases) - Generator Updates: One PR for CLI/IR updates (merge first), then separate PR(s) for generator changes
- IR Migrations: Only required for major IR bumps — add under
/packages/cli/generation/ir-migrations/
Key Points: Multiple PRs required, automatic publishing via versions.yml, generators use published (not workspace) IR versions. Forgetting to bump ir-types-latest/VERSION means no new @fern-fern/ir-sdk is published and the new field is invisible to downstream consumers.
Other Core Workflows
- Documentation: Markdown processing + API references → Static site
- Validation: Schema validation + reference checking + example verification
Important Files & Locations
- CLI Entry:
packages/cli/cli/src/cli.ts - IR Schema:
packages/ir-sdk/(central data structure) - Generator Base:
generators/base/(shared generator infrastructure) - Workspace Loading:
packages/cli/workspace/loader/ - Configuration:
packages/cli/configuration/ - Build Config:
turbo.json,pnpm-workspace.yaml
Development Notes
- Generator Development: Implement
AbstractGeneratorCli, use IR as input, follow existing language patterns - Generator-Specific Documentation: Each major generator has its own CLAUDE.md file:
generators/python/CLAUDE.md- Python v1+v2 tandem systemgenerators/java/CLAUDE.md- Java v1+v2 tandem systemgenerators/go/CLAUDE.md- Go v1+v2 tandem systemgenerators/typescript/CLAUDE.md- Legacy TypeScript generatorgenerators/ruby-v2/CLAUDE.md- Modern Ruby generator (standalone)generators/csharp/CLAUDE.md- Modern C# generator
- IR Changes: Require migrations in
packages/generation/ir-migrations/ - Testing: Always run
pnpm test:etefor end-to-end validation after CLI changes - Monorepo: Use Turbo filters for focused builds/tests on specific packages
- Docker: Generators run in Docker containers for isolation and consistency
TypeScript Rules
Typing
Never use any. If the type is truly unknown, use unknown and narrow it with type guards. If you're tempted to use any, stop and find the correct type or create one.
Never use as X for type assertions unless you have information the compiler cannot infer. Valid uses are rare—typically only when working with DOM APIs, test mocks, or deserializing JSON where you've validated the shape. If you need to assert, prefer satisfies for validation without widening.
Never use as any or as unknown as X. These are escape hatches that bypass the type system entirely. If the types don't line up, fix the types.
Never use non-null assertions (!) unless you can prove the value is defined and the compiler simply cannot see it. Prefer optional chaining (?.), nullish coalescing (??), or explicit null checks.
Never use @ts-ignore. If you must suppress an error, use @ts-expect-error with a comment explaining why, and only as a last resort.
Never use loose types like object, {}, or Function. Use specific object shapes, Record<K, V>, or typed function signatures like () => void.
Always provide explicit return types for exported functions and public methods. This serves as documentation and catches accidental return type changes.
Prefer named type guard functions over inline in checks. Instead of scattering "prop" in obj && obj.prop === value throughout business logic, extract these into well-named type guard functions (e.g., isInlineSchema(s), schemaAllowsNull(s)). This keeps call sites readable and centralizes the narrowing logic. Use TypeScript's x is T return type for type guards that narrow.
Prefer type guards and discriminated unions over type assertions for narrowing. Write custom type guards rather than asserting.
Prefer unknown over any in generic constraints when the type truly varies. Use <T> or <T extends SomeBase> rather than accepting any.
When working with external data (API responses, JSON parsing), validate and narrow with type guards—never assert the shape blindly.
Exhaustive Checks
Always handle all cases when switching on discriminated unions. Every switch statement on a discriminated union's type field must include a case for every variant. The default case must call assertNever from @fern-api/core-utils to ensure compile-time exhaustiveness—if a new variant is added to the union, any unhandled switch will fail to compile.
import { assertNever } from "@fern-api/core-utils";
switch (shape.type) {
case "circle":
return handleCircle(shape);
case "square":
return handleSquare(shape);
default:
assertNever(shape);
}Never leave a default case that silently ignores unknown variants. The whole point of assertNever is to turn missed cases into compile-time errors rather than silent runtime bugs. If you find yourself wanting to skip a variant, handle it explicitly (even if the handler is a no-op with a comment explaining why).
This applies to all discriminated union patterns in the codebase, including IR types, generator configuration unions, OpenAPI schema variants, and any other tagged union. Use assertNeverNoThrow from @fern-api/core-utils only when you intentionally want to ignore unexpected variants without throwing (e.g., forward-compatible parsing), and add a comment explaining why.
Here are additional TypeScript rules beyond type safety:
Async/Await & Promises
Never use .then() chains when async/await is available. Prefer linear async code over nested callbacks or promise chains.
Never forget to await a Promise. Unhandled promises silently fail. If you intentionally don't await, assign to void and add a comment explaining why.
Never use async on a function that doesn't await anything. It adds unnecessary overhead and obscures intent.
Error Handling
Never swallow errors with empty catch blocks. At minimum, log the error. If you truly want to ignore it, add a comment explaining why.
Never throw strings or plain objects. Always throw Error instances (or subclasses) to preserve stack traces.
Prefer early returns over deeply nested conditionals. Guard clauses make code easier to follow.
Immutability & Mutation
Never mutate function parameters. Create new objects/arrays instead. Use spread, map, filter, not push, splice, or direct assignment.
Prefer const over let. Only use let when reassignment is actually necessary.
Never use var.
Imports & Modules
Never use default exports. Named exports are easier to refactor, auto-import, and grep for.
Never use require() in TypeScript. Use ES module import syntax.
Keep imports organized. External dependencies first, then internal modules, then relative imports.
Naming & Structure
Never use abbreviations in variable names unless universally understood (e.g., id, url). Write response, not res. Write error, not err.
Never use I prefix for interfaces. Just name the thing what it is.
Prefer pure functions where possible. Functions that depend only on their inputs are easier to test and reason about.
Generated Code Management
Identifying: Generated by Fern (not third-party tools). Common locations: /sdk/src/serialization/, /sdk/src/api/, /seed/ test fixtures.
Regenerating: pnpm fern generate [--group <name>] or pnpm fern:local generate for local testing
Validation: Run pnpm compile to check for issues. Test individual fixtures during development. Run full validation (pnpm check:fix, pnpm test, pnpm test:ete) only when changes are complete.
Seed Testing & Fixtures
Adding/Updating Fixtures
New fixtures: Create /seed/<generator>/<fixture>/ directory → Add seed.yml config → Run pnpm seed:build → Run pnpm test:update and pnpm test:ete:update → Validate → Commit
Update fixtures: pnpm seed:build --filter <fixture-name> or pnpm test:update for snapshots
Pull Request Guidelines
When creating pull requests in this repository:
PR Title: Must follow semantic commit message rules enforced by CI (
.github/workflows/lint-pr-title.yml). Format:<type>(<scope>): <description>. Both type and scope are required.Allowed types:
fix,feat,revert,break,choreAllowed scopes:
docs,changelog,internal,cli,typescript,python,java,csharp,go,php,ruby,seed,ci,lint,openapi,deps,deps-dev,pydantic,ai-search,swift,rust,generator-cli,parser,ir,cli-v2,cli-generatorExamples:
chore(docs): update guidelines,feat(python): add new feature,fix(cli): resolve config loading bug- Assignee: Always assign the person who prompted you to create the PR as the assignee
- Description: Follow the PR template in
.github/pull_request_template.md - Testing: Ensure all tests pass before marking PR as ready for review
Architecture Decision Records (ADRs)
ADRs live in docs/adr/ and are numbered sequentially (0001-, 0002-, …).
Create an ADR when a change is cross-cutting — i.e., it affects how multiple components of the repo work together or sets a convention that all contributors must follow:
- A new repo-wide system or workflow (release pipelines, CI frameworks, build tooling)
- A design decision that governs the IR or the contract between the CLI and generators broadly
- A new architectural pattern or abstraction adopted across several packages
- A policy change that constrains how all (or many) generators/packages must behave
Do NOT create an ADR for:
- Changes scoped to a single generator or package, even significant ones (new features, output format changes, config additions)
- Bug fixes at any level
- Dependency version bumps
- Refactors that don't change observable behavior
- IR additions that are additive and don't change existing generator contracts
ADR format
# ADR NNNN: <Title>
## Status
Accepted — merged #<PR> on <date>.
## Context
Why this change was needed and what constraints shaped the design.
## Decision
What was decided and the key implementation details.
## Alternatives Considered
Other approaches evaluated and why they were rejected.
## Consequences
Trade-offs, limitations, and follow-on implications.After writing the ADR, number it by finding the highest existing docs/adr/NNNN-*.md and incrementing by one.
Troubleshooting
For Sentry buildwithfern / cli false-positive triage, see the Devin skill at .devin/automation/sentry-triage/SKILL.md, plus .devin/automation/sentry-triage/DESIGN_CHOICES.md and the per-issue ledger files under .devin/automation/sentry-triage/ledger/.
Quick Fixes by Issue Type
- Generator failures: Check
docker ps→ Rebuild image → Check container logs - IR compilation:
pnpm fern check→ Check circular refs → Review migrations - Test failures: Unit (check generated code) | E2E (
pnpm fern:build) | Seed (pnpm seed:build) | Lint (pnpm format:fix) - Performance: Use Turbo filters |
pnpm cleanthen rebuild | Check Docker limits
Debug Locations
- Build outputs:
dist/,.turbo/directories - Test outputs:
/seed/<generator>/<fixture>/directories
Individual Preferences
@~/.claude/my-fern-instructions.md
Trending
More talk lately.about the whole repository
Who's talking about fern-api/fern
- A Hacker News story“Show HN: Fern, a language for defining REST APIs that compiles into OpenAPI”Hacker News · Jan 11, 2023 · 18 points
- A Hacker News story“Fern: A cross-language alternative to tRPC”Hacker News · Mar 7, 2023 · 5 points
- A Hacker News story“Fern – An Alternative to OpenAPI”Hacker News · Jun 30, 2022 · 3 points
- A Hacker News story“Fern: Toolkit to generate SDKs and Docs for your API”Hacker News · Apr 3, 2024 · 2 points
- apet97/clockify-ts-sdk“feat: G-track sweep — G.1 idiomatic names, G.5 last-page, env-vars”GitHub · May 24, 2026 · 1 reactions
The biggest 5 of 33 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 33
Talked about on GitHub, Hacker News, Bluesky and Stack Overflow (33 times).
On GitHub · 26
- May 24, 2026feat: G-track sweep — G.1 idiomatic names, G.5 last-page, env-vars — apet97/clockify-ts-sdk1 reaction
- Mar 3, 2026[Data migration script] Misc improvements — langfuse/langfuse-docs1 reaction · 4 comments
- Aug 27, 2025feat(rust): Unify error handling with ApiError system — iamnamananand996/fern1 reaction · 1 comment
- Dec 20, 2024[SC-5624] Use Block Strings for Typically Long Strings — vellum-ai/vellum-python-sdks1 reaction
- Dec 24, 2023Mention SDK generation approaches — PradeepLoganathan/pradeepl-blog1 reaction · 3 comments
21 more on GitHub
- Oct 28, 2026docs: document page-actions.options.mcp-server-name — fern-api/docs0 reactions · 1 comment
- Oct 25, 2026chore(deps): bump fern-api from 5.152.2 to 5.171.1 — dsainvg/decide-extract-sdk0 reactions
- Oct 18, 2026feat(census): select the feature combinations worth proving and declare them in the census — nickderobertis/crozier0 reactions
- Oct 15, 2026fix: reject "." and ".." path parameter values — fern-demo/internal-node-auth00 reactions · 1 comment
- Oct 8, 2026docs(sdks): document refresh-auth-on-failed-permissions for TS, Python, and Java — fern-api/docs0 reactions · 2 comments
- Aug 26, 2026docs: fern.config.json pins version to "latest", should use a fixed version — dsx-ai-factory/nvke0 reactions · 1 comment
- Aug 16, 2026chore(deps-dev): bump fern-api from 5.89.3 to 5.96.0 — promobase/ad-platform-sdks0 reactions
- Apr 28, 2026build(deps-dev): bump fern-api from 4.67.0 to 4.106.0 — remarkablemark/openapi-generator-examples0 reactions
- Mar 6, 2026Bump fern-api from 3.91.5 to 4.9.0 — doc-detective/docs0 reactions
- Jan 7, 2026SDK CodeGen from API — davidkhala/code-dev-collection0 reactions
- Oct 27, 2025Bump fern-api from 0.16.22 to 0.95.2 — Wiqitanoli/let0 reactions · 1 comment
- Oct 27, 2025Bump fern-api from 0.16.22 to 0.95.2 — NeonSyntax14/kanban-board-api-50 reactions · 1 comment
- Oct 27, 2025Bump fern-api from 0.16.22 to 0.95.2 — hamstershleter7/saved0 reactions · 1 comment
- Apr 7, 2025chore(deps-dev): bump fern-api from 0.16.22 to 0.57.16 — revertinc/revert0 reactions · 2 comments
- Nov 30, 2024User reports high CPU utilization — cohere-ai/cohere-typescript0 reactions · 1 comment
- Nov 4, 2024:herb: :sparkles: [Scheduled] Upgrade Fern CLI — THEFIG06/superagent0 reactions · 1 comment
- Oct 14, 2024:herb: :sparkles: [Scheduled] Upgrade Fern CLI — eXa-online/fern-website0 reactions
- Jul 29, 2024Release checklist — GooeyAI/typescript-sdk0 reactions
- Mar 19, 2024feat: automatic api docs — edgenai/edgen0 reactions · 1 comment
- Dec 4, 2023Test fern for the automatic creation of a client SDK based on the backend api — Agenta-AI/agenta0 reactions · 2 comments
- May 9, 2023Look at OpenAPI generator — gritcsenko/HomeInventory0 reactions · 1 comment
On Hacker News · 5
- Jan 11, 2023Show HN: Fern, a language for defining REST APIs that compiles into OpenAPI18 points · 7 comments
- Mar 7, 2023Fern: A cross-language alternative to tRPC5 points · 1 comment
- Jun 30, 2022Fern – An Alternative to OpenAPI3 points
- Apr 3, 2024Fern: Toolkit to generate SDKs and Docs for your API2 points
- Jan 5, 2023Fern keeps your docs and SDKs in sync with your API1 point
On Bluesky · 1
- Apr 22, 20258. Fern - API design and documentation tool Fern is an open-source tool that streamlines API design, documentation, and code generation for… — @madza.dev1 likes and repost · 1 reply
On Stack Overflow · 1
- Jun 16, 2022How to add openapi.yaml to your project0 votes
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

