unsubbed.co

Kinto

Kinto gives you minimalist JSON storage service with synchronisation and sharing abilities on your own infrastructure.

A generic JSON document store with sync and sharing — honestly reviewed for founders who want to escape Firebase.

TL;DR

  • What it is: A minimalist REST API server that stores JSON documents in collections, with built-in offline sync and permissions — think Firebase Firestore, but Python-based, self-hosted, and open-source [README].
  • Who it’s for: Developers building offline-first web or mobile apps that need a lightweight, self-controlled backend for JSON data sync. Not a ready-to-use application — it’s infrastructure [README][1].
  • Cost savings: Firebase Firestore’s Blaze plan charges per read/write at scale. Self-hosted Kinto runs on a $5–10/mo VPS with no per-operation pricing. The savings math works, but only if you have a developer to integrate it.
  • Key strength: Dead simple data model (buckets → collections → records), a clean HTTP API, and a mature JavaScript client (kinto.js) that handles offline-first IndexedDB sync out of the box [1].
  • Key weakness: It’s a developer primitive, not a product. There’s no admin UI, no dashboard, no drag-and-drop anything. A non-technical founder cannot use this without an engineer. Independent third-party reviews are nearly nonexistent — this tool has largely flown under the radar since its Mozilla-era heyday.

What is Kinto

Kinto is a Python-based HTTP server that stores arbitrary JSON documents. You POST a document to a collection, it saves it to PostgreSQL, returns it on GET, and — crucially — can sync that data back to a JavaScript client running in a browser, even when the browser was offline [README][1].

The project came out of Mozilla Services in the mid-2010s. Mozilla used it to back Firefox preferences sync and other internal services. In 2016 it was prominent enough to appear as a mentored Outreachy internship project [4]. Today it sits at 4,426 GitHub stars, 426 forks, and 127 contributors, with 204 releases and an actively maintained codebase — the latest release (25.0.3) landed March 3, 2026 [README].

The data model is deliberately minimal. Everything is organized as: bucket → collection → record. Each bucket is an isolated namespace. Each collection holds JSON records with automatic ID, timestamp, and version fields. Permissions are attached at each level — you can make a collection world-readable and write-only for authenticated users, or lock it down to a single account [README][1].

The companion JavaScript library, kinto.js, handles the other half of the value proposition. It syncs a local IndexedDB database to your Kinto server, resolves conflicts, and keeps working when the network is gone — your app reads and writes locally, and kinto.js pushes changes to the server when the connection comes back [1].

What Kinto is not: it’s not a full backend framework, not a database, not a CMS, not a file storage system (despite being catalogued under “file-management”). It’s closer to a stripped-down, self-hosted Firebase Realtime Database — if Firebase were a clean REST API with explicit collection semantics instead of a JSON tree.


Why people choose it

Independent third-party reviews of Kinto are sparse — this tool has never attracted the blog-post attention of n8n or Supabase. What context exists comes from its documentation, tutorials, and the Mozilla open-source community. That scarcity is itself a signal: Kinto solves a specific, well-defined problem (offline-first JSON sync) and doesn’t try to be anything else.

The reasons that appear consistently in documentation and community references:

Escape Firebase lock-in. Firebase’s free tier is generous until it isn’t. Once you’re on the Blaze plan, reads and writes accumulate into real bills. More importantly, your data lives on Google’s servers. Kinto’s entire value proposition is that you run the server, you own the data, and there’s no metered API call that can surprise you mid-month [README].

The data model is auditable. Firebase’s NoSQL JSON tree is flexible but opaque — queries require learning Firestore’s composite index system. Kinto stores records in PostgreSQL, which means you can connect any Postgres-compatible tool (psql, Metabase, DBeaver) and query your data directly without going through the API [README].

Offline-first without the ceremony. The kinto.js tutorial demonstrates building a functional offline-first todo app in under 50 lines of JavaScript [1]. The sync logic — conflict detection, retry on reconnect, local-first reads — is handled by the client library. You don’t implement any of it.

Built and battle-tested at Mozilla. The project has 8,947 commits and 204 releases [README]. This isn’t an alpha experiment — it was used in production at Mozilla for years. That history means edge cases have been found and fixed.


Features

Based on the README, documentation, and kinto.js tutorial:

Core storage engine:

  • REST HTTP API: GET, POST, PUT, PATCH, DELETE on buckets, collections, and records [README]
  • Automatic versioning of records with last_modified timestamp [1]
  • Batch endpoint for multi-operation requests
  • Server-side filtering, sorting, and pagination on collections [README]
  • PostgreSQL backend for production; in-memory backend for development/testing [README]

Sync and sharing:

  • Conflict detection using ETag and If-Match headers
  • Client-side offline sync via kinto.js (IndexedDB + automatic conflict resolution) [1]
  • Bucket and collection-level permissions (read, write, create) [README]
  • Shared collections accessible by multiple authenticated users [README]

Authentication:

  • Pluggable auth backends (basic auth, Firefox Accounts, custom)
  • Per-resource ACLs: each bucket, collection, and record can have its own access list [README]

Developer experience:

  • Docker image available (kinto/kinto-server) [README]
  • Docker Compose file included in the repo [README]
  • Active Python package on PyPI [README]
  • ReadTheDocs documentation [README]
  • kinto.js JavaScript client for browser sync [1]

What’s missing:

  • No admin dashboard or web UI included — you manage data via API or third-party tools
  • No built-in file/binary storage (records are JSON only)
  • No real-time push (WebSockets) in the base server — polling or separate plugin needed
  • No built-in query language beyond simple filter parameters

Pricing: SaaS vs self-hosted math

Kinto has no official SaaS offering. It is purely self-hosted. The cost equation is simple: server costs vs. whatever you’d pay for a comparable managed service.

Comparable managed alternatives:

  • Firebase Firestore (Blaze plan): $0.06 per 100K document reads, $0.18 per 100K writes, $0.108/GB/month storage. Free tier covers 50K reads/day, 20K writes/day, 1GB storage. At meaningful scale (e.g., 1M reads/day), that’s ~$18/day or ~$540/month just in read costs.
  • Supabase: Free tier is generous. Pro plan starts at $25/month per project, includes 8GB database, 250GB bandwidth. More full-featured than Kinto.
  • PocketBase: Free, self-hosted, single binary — closer comparison to Kinto, no SaaS version.

Self-hosted Kinto:

  • VPS: $5–10/month (Hetzner CX11, DigitalOcean Basic, Contabo)
  • PostgreSQL: bundled in the docker-compose or add $5–15/mo for managed Postgres if you want that off your plate
  • Your time: non-trivial initial setup; ongoing maintenance is minimal once running

Concrete math: If you’re building an app with 500K Firestore reads per day (moderate traffic), that’s roughly $90–100/month on Firebase Blaze. Kinto self-hosted on a $6 Hetzner VPS: $6/month. That’s ~$1,100/year saved — but only if a developer is already in the picture. The self-hosting cost isn’t paid in money; it’s paid in engineering hours.


Deployment reality check

Kinto supports Docker deployment with an included docker-compose.yml [README]. The stack is: Kinto Python server + PostgreSQL. No external services required beyond that.

What you actually need:

  • A Linux VPS (1GB RAM minimum; 2GB comfortable for production load)
  • Docker and docker-compose
  • PostgreSQL 9.5+ (bundled in docker-compose, or external managed Postgres)
  • A domain and reverse proxy (nginx, Caddy) for HTTPS if you’re exposing it publicly
  • Python 3.10+ if you’re not using Docker

What can go sideways:

  • The in-memory backend is the default and loses all data on restart — you must configure PostgreSQL for any real use [README]. This bites developers who test locally and forget to switch backends.
  • There is no admin interface. You manage Kinto entirely through its HTTP API or via psql directly. Non-technical operators have no option here.
  • The kinto.js sync client [1] uses a public test server (https://kinto.dev.mozaws.net) that purges data every 24 hours — easy to accidentally build against the test server and lose data.
  • Kinto’s permissions model (nested ACLs on buckets/collections/records) is powerful but requires careful design upfront. Getting permissions wrong at the collection level means rebuilding your data structure.
  • The project’s ecosystem is smaller than Supabase or Firebase — when you hit a wall, you’re often reading the official docs or source code rather than finding a Stack Overflow answer.

Realistic time estimate: For a developer with Docker experience: 30–60 minutes to a working instance. For someone building an actual offline-sync app on top of it: 1–3 days to understand the data model, set up kinto.js, and design the collection structure correctly.


Pros and Cons

Pros

  • Genuinely minimal. The core API is learnable in an afternoon. Bucket, collection, record — that’s the entire mental model. No query planner to tune, no schema migrations to write for basic use [README][1].
  • Offline-first first-class. kinto.js handles IndexedDB sync, conflict resolution, and retry logic out of the box. Building offline-capable web apps without this requires implementing all of that yourself [1].
  • PostgreSQL-backed. Your data is in a real relational database with standard tooling. Backups, direct queries, replication — all standard Postgres operations work on Kinto’s data [README].
  • Long-term maintenance track record. 204 releases, 8,947 commits, latest release in March 2026 — not an abandoned project [README].
  • Docker-native. First-class Docker support with an included Compose file lowers the deployment barrier for anyone comfortable with containers [README].
  • Mozilla lineage. The codebase has been production-tested at Mozilla scale. That matters for a backend storage component [4].
  • No per-operation billing. Self-hosted means no metered API calls. A spike in reads doesn’t generate an invoice [README].

Cons

  • No admin interface. Zero. You manage everything through HTTP API calls or direct database access. This is a hard blocker for any non-technical operator.
  • Not a product, a component. Kinto doesn’t do anything useful by itself — it’s a building block. You build the application on top of it. That’s the opposite of what a non-technical founder needs.
  • Scant third-party reviews. No serious independent reviews exist. This makes evaluating real-world limitations and gotchas harder — you’re largely relying on the official docs.
  • Limited ecosystem. Kinto.js is the only mature client library. If you’re building in Swift, Kotlin, or Python clients, you’re writing HTTP calls yourself or finding thin community wrappers.
  • Permission model complexity. The hierarchical ACL system is powerful but not obvious. Mistakes at the bucket level cascade down to all collections and records inside it — and fixing them means migrating data.
  • License is unclear from automated detection. The profile shows “NOASSERTION” for license. The GitHub repository itself shows “License View license” — Apache 2.0 is standard for Mozilla-originated projects, but you should verify against the LICENSE file before commercial deployment.
  • No real-time push. If your application needs WebSocket-style live updates (records changing in real time without polling), Kinto’s base server doesn’t provide this. You’d need to build a polling loop or integrate a separate pub/sub layer.
  • The Mozilla era is over. Kinto was built to solve Mozilla’s internal sync needs. Mozilla has since moved on. The project is community-maintained, which is fine for stability, but there’s no commercial entity with financial interest in its future growth.

Who should use this / who shouldn’t

Use Kinto if:

  • You’re a developer building an offline-first web or mobile app and you want your sync backend to live on your own server instead of Firebase.
  • You need a simple REST API to store JSON documents with per-user access control and you’d rather write 20 lines of HTTP calls than integrate a heavier backend framework.
  • You want your users’ data in a PostgreSQL database you control, not on Google’s servers.
  • You’ve used Firebase Firestore and the billing started hurting — and you have a developer who can handle the migration.

Skip it (use Supabase instead) if:

  • You need auth, storage, real-time subscriptions, and an auto-generated REST/GraphQL API from a single Postgres schema. Supabase does all of that with an actual admin dashboard.

Skip it (use PocketBase instead) if:

  • You want a self-hosted backend with an admin UI, file uploads, and auth — deployed as a single binary with no Docker or PostgreSQL required. PocketBase is the modern Kinto for non-developers.

Skip it entirely if:

  • You’re a non-technical founder. There is no path to using Kinto without writing code. This is not a CMS, not a no-code tool, not a dashboard.
  • You need real-time push. Kinto doesn’t have it.
  • You need a production-grade auth system. Kinto’s auth is pluggable but basic — Firebase Auth or Supabase Auth are far more complete.

Alternatives worth considering

  • Supabase — open-source Firebase alternative with PostgreSQL, auth, storage, real-time, and an admin dashboard. Far more complete than Kinto. Self-hosted or managed cloud.
  • PocketBase — single-binary backend with admin UI, file storage, auth, and real-time subscriptions. Written in Go. Much easier to deploy and manage than Kinto for comparable use cases.
  • Firebase Firestore — the obvious managed alternative. Generous free tier, real-time built-in, massive ecosystem. Costs money at scale and locks you into Google.
  • CouchDB + PouchDB — the original offline-first sync stack. PouchDB in the browser syncs to CouchDB on the server. More battle-tested for offline-first than Kinto, though also more complex.
  • Directus — self-hosted headless CMS / data platform with a visual interface, REST and GraphQL APIs, and a strong no-code admin. If you need something non-technical people can operate, this is the direction.
  • Appwrite — open-source backend-as-a-service with auth, database, storage, and functions. Closer to Firebase in scope than Kinto.

For a developer wanting offline-first JSON sync specifically, the realistic shortlist is Kinto vs CouchDB vs PocketBase. Kinto wins if you want clean REST semantics and direct PostgreSQL access. CouchDB wins if you need the most battle-tested offline sync engine available. PocketBase wins if you want everything in one binary.


Bottom line

Kinto is a well-built, honestly narrow tool. It does one thing — store JSON documents in PostgreSQL with sync and sharing via HTTP — and it does it cleanly. The Mozilla engineering heritage shows in the API design and the kinto.js client library. The 204 releases and active maintenance mean it’s not going to disappear.

But Kinto’s era of relevance may have passed. When Kinto was built (2015–2018), the self-hosted backend-as-a-service space was nearly empty. Now Supabase, PocketBase, Appwrite, and Directus all solve similar problems with admin interfaces, richer feature sets, and larger communities. For a non-technical founder trying to escape Firebase bills, none of those tools are Kinto — and all of them are easier to operate.

Kinto remains a legitimate choice for a developer who specifically wants a minimal, PostgreSQL-backed JSON sync API with offline-first client support, no operational complexity beyond a docker-compose up, and no per-operation billing. That’s a real use case. Just don’t expect it to be anything other than exactly that.


Sources

  1. Kinto.js Documentation — Tutorial (kinto.js offline-first sync tutorial using Kinto server). https://kintojs.readthedocs.io/en/latest/tutorial/
  2. facts.dev — Solidus project details (mentions Kinto in related projects section). https://www.facts.dev/p/solidus/
  3. Daily Mail — Toyota Kinto announcement (Toyota car-sharing service, unrelated to Kinto software). https://www.dailymail.co.uk/sciencetech/article-7887271/Toyota-announces-new-subscription-leasing-car-share-programs-called-Kinto-Europe.html
  4. Mozilla Wiki — Outreachy Round 11 (Kinto listed as Mozilla Outreachy internship project, 2016). https://wiki.mozilla.org/Outreachy/Round/11

Primary sources: