OpenCan v2.0.0 is out — an open-source, self-hostable alternative to Canny. AGPL-3.0, deploys with a single Docker Compose file.
This post covers what it does, the stack, and — what I think is the more interesting part — the development methodology I used to build it: spec-first, AI-assisted, with mandatory review passes before anything shipped.
Repo: https://github.com/sriramgopalan/opencan
Demo: https://demo.opencan.dev
Docs: https://opencan.dev/docs
What OpenCan Does
The core loop: customers submit and vote on feature requests → posts move through a status lifecycle (Open → Under Review → Planned → In Progress → Shipped) → voters get automatically notified by email when something they asked for ships.
Around that loop:
- Public roadmap page, grouped by status
- Changelog with Markdown support and voter email notifications
- Embeddable in-app widget with JWT auto-login, so users don't see a second sign-in screen
- AGPL-3.0, self-hosted, your data on your server
If you've used Canny and wondered why a voting board with status fields and email notifications costs what it costs, this is the answer to that question.
Stack
Next.js, TypeScript (strict mode), tRPC, Prisma, PostgreSQL, Redis, MinIO. The marketing site is a separate Astro build. Deployed via Docker Compose. I run my own instance on a Hostinger VPS.
The Methodology: Spec First, Always
Here's the part I actually want to talk about.
I write a development philosophy series I call Rightcoding — the argument that vibecoding (accepting whatever the model outputs, iterating until it looks like it works) produces software that demos well and holds badly. OpenCan was built as the proving ground for the alternative.
The rule: every feature gets a full written spec — every decision resolved, every edge case considered — before any code is generated. Not a rough outline. The spec is the source of truth. The code is the artifact that proves the spec is implementable.
Why this matters specifically for AI-assisted development: AI is extraordinarily good at implementing a clear, unambiguous specification. Given a precise description of what a feature should do, how it should handle edge cases, and what its security constraints are, Claude Code produces code that's close to correct on the first pass — and genuinely inspectable, because you wrote down what "correct" means before generation started.
Without a spec, the same tooling produces something different. You describe a vague intention, the model infers a reasonable interpretation, you iterate until it looks right. It ships. It also drifts — from what you actually wanted, from consistency with adjacent features, from a security model you had in mind but never wrote down. That drift is invisible until it isn't.
Three Mandatory Review Passes
Every feature went through three passes before I considered it done:
1. Spec adherence. Does the implementation actually do what the spec says — not what it appears to do, not what the tests verify. This means reading the code and following the logic, not skimming the shape.
2. Security. Every path handling user input. Every authorization boundary. Every database query touching multi-tenant data. AI is genuinely unreliable here — not because it writes obviously broken code, but because it writes plausible code that looks secure and isn't. There's a well-documented finding that models asked to fix security vulnerabilities often introduce more than they resolve. That's not theoretical — it's a hazard I encountered directly, and caught because I was specifically looking for it.
3. DRY. After correctness and security: duplication. In an AI-assisted codebase, where the model regenerates solutions to problems it's already solved elsewhere, duplication accumulates faster than in hand-written code. This pass exists specifically to catch and collapse it.
Three passes is slower than vibecoding. It's also faster than debugging an auth vulnerability eight months post-launch because nobody looked hard enough at what the model produced.
Where I Trusted AI Freely vs. Where I Didn't
Trusted freely, minimal supervision: boilerplate and scaffolding (route handlers, form components, schema migrations with clear before/after definitions), documentation updated continuously from existing code, test file structure, and refactors within a single well-understood module. These are local, syntactic, and immediately verifiable — low blast radius, low review cost.
Stayed skeptical, deep audit required: the JWT auto-login flow for the embeddable widget, every database query involving post visibility across workspaces, and the email notification pipeline's logic for who gets notified and when. The standard here: don't ship until you can explain every line to a senior engineer without saying "the AI wrote it." If I couldn't explain it, I didn't own it. If I didn't own it, it didn't ship.
Why Open Source, Why AGPL
OpenCan is free to self-host, fully featured — no crippled tier held back for a future paid version. The plan is open-core: a managed hosted tier later, for people who'd rather not run their own infrastructure, modeled on what DocuSeal and Plausible have done. I'd rather be upfront about that than pretend it's pure altruism.
AGPL-3.0 specifically because this is the kind of tool that's trivial to wrap as a hosted SaaS without contributing anything back — the network-use clause closes that gap in a way a permissive license wouldn't.
Publishing the methodology alongside the product was deliberate too. Code with sloppy AI-generated logic published to a public repo is an embarrassment with a git history attached. The bar for software you put your name on in public should be higher than the bar for code that only runs inside internal tooling.
Try It
Quickstart's in the docs — Docker Compose, one command, a few minutes to a running instance. Demo's at demo.opencan.dev if you want to poke around before deploying.
Genuinely interested in feedback from anyone who's evaluated Canny, Frill, or similar — what's missing, what would make this an actual replacement for your team.
Top comments (0)