Skip to content
← All projects

TypeScript · React 19 · Hono · Drizzle · PostgreSQL · Rust

Aircraft

A full-stack aircraft catalog joining a Rust scraper, PostgreSQL, a typed Hono API, and a React 19 frontend across one validated schema boundary.

Role
Sole author
Year
Claims
unverified
Progress
in progress

Status: in active development, and the repository is not public. The design below is current. Planned sections are not yet built, and nothing on this page can be checked against source until the repository is published.

Context and scope

A catalog of aircraft specifications, built end to end by one author across three languages. The application turns on three boundaries: scraped source data validated before import, an API contract shared with the frontend through TypeScript rather than through documentation, and view state stored in the URL rather than in components.

The scraper is a separate finished project, so the work here begins at the JSON it produces.

This is the client stage of a three-part aircraft system built since January 2026, and the only stage that is not built. The plane scraper and the aircraft management engine are both source-verified; this page is not.

Planned scope

  1. Catalog list with server pagination
  2. Faceted filtering through typed search parameters
  3. Detail route with a specification comparison drawer
  4. Favorites with optimistic updates and rollback
  5. Specification charts
  6. Seed pipeline with validation at the scraper boundary

System design

Data pipeline

plane-scraper produces JSON in Rust. A seed process validates that data before writing it to PostgreSQL through Drizzle. The validated schema is the contract between the Rust and TypeScript halves of the system, and it is the only place the two languages meet.

API contract

A Hono service serves the records and exports its route types. The client imports those types directly, so a change to a route signature surfaces as a compile error in the frontend rather than as a runtime failure in a browser.

Client state

Filters, sorting, pagination, and selection live in typed search parameters. That keeps a view shareable as a URL, correct after a reload, and compatible with browser navigation, none of which hold when the same state lives in component state.

Import-validation behavior

Scraped data is dirty by definition, so the seed boundary is where this system either holds or fails quietly.

Validation runs at import rather than at read. A record that does not match the schema is rejected there, because the alternative is a malformed row reaching the API and surfacing as an unexplained frontend error several layers away from its cause.

The design consequence is that the database is trusted downstream. The API does not re-validate shape, and the client trusts the API's exported types, which is only safe because the untrusted input was rejected at the single point where trust changes.

This is designed rather than demonstrated. The seed process is not built.

Design decisions

DecisionRationale
Hono RPC rather than tRPC or GraphQLThe server exports route types and the client imports them, so API changes become frontend compile errors. tRPC gives similar safety but produces an RPC surface rather than a real HTTP API. GraphQL adds schema and tooling cost without a need for flexible client queries.
Drizzle rather than PrismaKeeps queries SQL-shaped and migrations readable, and avoids a separate schema language and a query-engine binary. Prisma is more popular; Drizzle hides less.
React Compiler from the first commitThe compiler owns memoization from the start, so the codebase never accumulates manual useMemo, useCallback, or React.memo conventions that would later need unlearning.
The URL as the primary state storeFilters, sorting, pagination, and selection stay shareable, reload-safe, and correct under browser navigation.
A client-rendered SPA rather than a meta-frameworkThe catalog has no search-indexing requirement worth paying for, and a separate API with a separate client keeps the service boundary explicit and honest about what was built.

Verification status

Nothing here is verified. This page describes an architecture, not a running system, and the verified flag in its frontmatter says so.

An earlier version of this page linked github.com/rsstdd/aircraft as its repository. No such repository exists, publicly or privately, so the link answered 404 for every reader who tried it. The link has been removed rather than repointed, because a claim with a broken anchor is worse than a claim with no anchor: the first looks checkable and is not.

What will be checkable once it exists: whether a route-signature change actually fails the frontend build, whether the seed rejects malformed scraper output rather than passing it through, and whether the URL-driven state survives reload and back-navigation intact.

Known limitations

Status

Not finished. The planned scope above is a sequence rather than a description, and several items are untouched.

Data licensing

The source data is scraped from a third-party specification site through my own scraper. Local development is one thing and republishing that dataset is another, so a deployed version will use either a small attributed subset or an openly licensed source such as the FAA aircraft characteristics database.

Contact

Available now. Permanent senior or staff platform roles, in Munich or remote within the EU.

Email is the fastest way to reach me.