The Setup
A filament inventory system built for makers who actually use the stuff.
Printory started as a Flutter mobile app to solve a problem I lived with: dozens of filament spools, unreliable spreadsheets, and too many ruined prints. Four months later it's shipping on iOS, Google Play, and as a self-hosted web platform running on FastAPI, PostgreSQL, and Docker.
Kills the "empty spool surprise" mid-print.
Weight progress bars, status badges, and check-in/out tracking give makers a truthful view of what's actually on the shelf. No more starting an eight-hour print with a half-empty roll.
Turns a spreadsheet chore into a QR scan.
Each spool gets its own QR code. Scan to check in, check out, or log usage in seconds — the kind of friction-free capture that actually stays up to date because it's faster than not doing it.
Inventory with color indicators, status badges, material types, and weight progress bars.
The Landscape
Filament chaos and spreadsheets that go stale the moment you save them.
Any serious 3D printing hobbyist knows the drill: dozens of spools across materials, colors, and brands, tracked in a spreadsheet that's already wrong. Start a print, find an empty spool. Need a specific color, waste twenty minutes rummaging through bins.
Existing tools were either overbuilt enterprise inventory systems or hobby trackers that couldn't survive sharing a printer with someone else. Nothing felt like it was built by a maker for a maker — fast to log, honest about what's left, and easy to run on a phone or a home server.
Dashboard with inventory stats and chronological activity feed.
The Mission
Build an inventory tool that's faster than not using one.
Design and ship a filament tracker that handles real workshop complexity — materials, colors, weight, suppliers, locations — without asking the user to do more work than they'd do in a spreadsheet. Ship to app stores, then scale it to shared workshops without losing the simplicity.
The Moves
Four bets, from phone to self-hosted platform.
Write the PRD before writing any code
Started by writing a detailed PRD in Claude Code that defined the core user problem, the key workflows (scan, check-in, alert), and the data model for spools, materials, and usage history. Having that spec up front kept the first build from sprawling and made every later pivot a small rewrite instead of a rebuild.
Ship a Flutter mobile app in two months
The first version shipped as a Flutter mobile app in two months — local storage, QR generation with qr_flutter, and scanning via mobile_scanner. Launched on Google Play and the App Store to get it in the hands of real makers before scope-creeping into a platform.
Rebuild as a self-hosted web platform
User feedback from the app store launch surfaced a bigger need: teams sharing printers wanted a central inventory visible from any device. A local-only phone app couldn't serve that, so I wrote a second PRD for a web platform — PostgreSQL, FastAPI, and a vanilla JavaScript frontend with the same UX patterns that worked on mobile. Vanilla JS and CSS custom properties (no React, no Tailwind build step) keep the Docker image tiny and the deploy one command.
Reorder flow with priority, cost totals, and PDF export
The reorder system turned "I should buy more filament" into a structured list with priority levels, running cost totals, and one-click PDF export for shopping runs. Small thing, but it's the workflow that closes the loop between tracking inventory and actually keeping it stocked.
The Payoff
Two platforms, one inventory model, zero spreadsheets.
Printory now runs on both app stores and as a self-hosted web platform, serving solo makers who want offline-first tracking and shared workshops that need multi-device access against a PostgreSQL-backed source of truth. Same mental model, same UX patterns, two deploy targets.
Mobile + web platform shipped
Spec to App Store launch
One-command self-host
Looking Back
Ship the phone app. Let users tell you it needs to be a platform.
The instinct with a project like this is to architect the web platform from day one. The better move was shipping the Flutter app first and letting the feedback from the app store launch define the rewrite. The PRD-first workflow made the pivot cheap, and not over-engineering the initial version is what made it ship at all.