Working With AI Tools on a New Library

Published: (February 19, 2026 at 08:50 PM EST)
5 min read
Source: Dev.to

Source: Dev.to

Introduction

This is the setup guide for Railway‑Oriented TypeScript. If you haven’t read the overview yet, start there.

@railway-ts/pipelines and @railway-ts/use-form are new. That creates a practical problem: AI coding assistants — Claude Code, Cursor, GitHub Copilot — have been trained on millions of examples of Zod, react‑hook‑form, and neverthrow. They have almost no training data for @railway-ts.

The result is predictable. Ask Claude Code to build a form with @railway-ts/use-form installed and it will write zodResolver, useForm from react‑hook‑form, and setError/clearErrors — confidently, without being asked, because that pattern appears thousands of times in its training data. It isn’t hallucinating random code; it’s pattern‑matching the highest‑probability answer. The problem is that answer is wrong for your project.

This isn’t a criticism of AI tools. It’s a structural reality about how they work that’s worth understanding and routing around.

Why Docs Shipped With the Package Matter

Both libraries now ship their documentation inside the npm package:

node_modules/@railway-ts/pipelines/docs/
node_modules/@railway-ts/use-form/docs/

Modern AI coding tools — Claude Code in particular — can read your node_modules and reason from the types and documentation that are present. When you point the tool at the right docs, it stops pattern‑matching against its training data and starts reasoning from the actual library API. The generated code goes from “confidently wrong” to “reads the types and generates correct usage.”

The difference in output quality is substantial. The bundled docs are the mechanism that makes AI‑assisted development on a new library viable.

Setting Up a CLAUDE.md

The most reliable way to redirect an AI tool is a CLAUDE.md (or equivalent context file) in your project root. Claude Code reads this automatically. Create it before you start generating form or pipeline code:

# AI Coding Instructions

This project uses @railway-ts/pipelines and @railway-ts/use-form.

Before generating any form or pipeline code, read the docs shipped with the packages:

- node_modules/@railway-ts/pipelines/docs/
- node_modules/@railway-ts/use-form/docs/

Rules:

- Do NOT use Zod or @hookform/resolvers patterns
- Do NOT use react-hook-form's useForm, setError, or clearErrors
- Schema validation uses @railway-ts/pipelines/schema, not z.object()
- Form state uses useForm from @railway-ts/use-form, not react-hook-form
- Async pipelines use flowAsync/pipeAsync from @railway-ts/pipelines/composition

For other AI tools

ToolHow to apply the same guidance
CursorAdd the same content to .cursorrules or use the @Docs feature to index the bundled docs directly.
GitHub CopilotCopilot can’t be forced as directly, but keeping a reference file open in your editor with correct usage examples dramatically improves suggestion quality.

Verifying the Setup Works

After creating CLAUDE.md, ask your AI tool to build a simple form before touching any real code:

Build a React login form with email and password fields using @railway-ts/use-form. Handle server validation errors.

The output should:

  • use useForm from @railway-ts/use-form
  • build a schema with object / required / chain from @railway-ts/pipelines/schema
  • call form.setServerErrors() for server‑side error injection

If you still see zodResolver, @hookform/resolvers, or setError/clearErrors, the tool is still pattern‑matching against its training data — double‑check that CLAUDE.md is in the project root and that the docs are present in node_modules.

What the AI Gets Right Once Pointed at the Docs

When the tool reads the bundled docs, it handles the following well:

  • Schema composition with chain, object, required, optional
  • fieldValidators for async field‑level checks
  • form.setServerErrors() for server‑side error injection
  • flowAsync / pipeAsync for composing multi‑step async pipelines
  • Curried operators: mapWith, flatMapWith, filterWith, tapWith, etc.
  • Batch processing helpers: combine, combineAll, partition
  • Cross‑field validation with refineAt

Things worth double‑checking manually

  • Type inference with InferSchemaType — verify the generated type matches your intent.
  • initialValues completeness — TypeScript will error if a field is missing, but confirm it aligns with your UI.
  • Error path strings in setServerErrors — ensure they match your schema field names.

Quick Start

mkdir my-project && cd my-project
npm init -y
npm install react react-dom @types/react typescript
npm install @railway-ts/pipelines @railway-ts/use-form

Create CLAUDE.md as shown above, then verify the docs are present:

ls node_modules/@railway-ts/pipelines/docs/
ls node_modules/@railway-ts/use-form/docs/

Migrating an existing project that uses Zod

npm install @railway-ts/use-form @railway-ts/pipelines
# keep zod — the form hook accepts Zod schemas via Standard Schema v1

You can adopt the form hook without touching your Zod schemas. See Part 3 for the migration path.

The Series

Part 1 — Form Hook Deep Dive

Composable async pipelines in TypeScript – one result type, zero adapters (Part 1)

  • Walk‑through of the useForm hook internals:
    • Resolver wiring
    • Async validation handling
    • Server‑error conversion
    • Type assertions
  • Followed by the same form rewritten without any of those pieces.

Part 2 — Composable Async Pipelines

Composable async pipelines in TypeScript – one result type, zero adapters (Part 2)

  • Introduction to the @railway-ts/pipelines API:
    • Result type
    • Curried operators
    • flowAsync for multi‑step async pipelines where errors short‑circuit automatically
  • Shows the exact same Result type used by the form hook.

Part 3 — Schema‑First React Forms

Schema‑first React forms – one schema, three error layers, zero glue (Part 3)

  • Detailed explanation of the 3‑layer error priority system
  • Handling of array fields
  • Full‑stack loop: a single schema drives both backend pipeline validation and frontend form state without any format conversion.

Bonus — Data Processing Pipelines

Building a type‑safe data‑processing pipeline in TypeScript (Bonus)

  • Uses the pipeline library in an ETL context:
    • Batch processing with combine, combineAll, and partition
    • Reusable sub‑pipelines
    • Structured error reporting
  • No React, no UI – pure data processing.

GitHub Repositories

0 views
Back to Blog

Related posts

Read more »

Warm Introduction

Introduction Hello everyone! I'm fascinated by the deep tech discussions here. It's truly amazing to see the community thrive. Project Overview I'm passionate...