Airtable is wonderful until it is not. Then you hit the row limit, the API rate cap, the per-seat pricing cliff — and realise that all your data lives somewhere you cannot easily leave. Teable was built to fix that. It looks like a spreadsheet, behaves like a database, runs on your own server, and does not flinch at a million rows.

What is Teable?

Teable is an open-source no-code database platform with a spreadsheet-style interface. Teams use it to manage projects, track inventory, build internal tools, collect form data, and collaborate in real time — without writing a single line of SQL.

“Teable uses a simple, spreadsheet-like interface to create powerful database applications. Collaborate with your team in real-time, and scale to millions of rows.”

The key architectural decision that sets it apart: your data lives in real PostgreSQL tables. Not a custom binary format, not a JSON blob column — actual relational tables you can query directly with any SQL tool.

Teable Source Code on GitHub Teable Documentation Template Gallery

Why teams choose Teable

  • 📊 Real-time collaboration — multiple users edit simultaneously with Operational Transformation (the same tech as Google Docs), no last-write-wins conflicts
  • 🚀 Millions of rows — a WebGL-accelerated virtualised grid keeps scrolling smooth at any scale
  • 🐘 Real PostgreSQL — your data is in actual PG tables; query it with psql, Metabase, or any BI tool
  • 🔌 Five view types — Grid, Kanban, Gallery, Form, Calendar
  • 🧩 Plugin system — extend with custom views and panels via an iframe SDK
  • 📤 Import / Export — CSV, Excel, direct SQL access via exposed PG proxy port
  • 🔐 Self-hosted, AGPL-3.0 — full data sovereignty, no per-row or per-seat limits you do not set yourself
  • 🌐 i18n — translations managed via Crowdin, multiple languages out of the box

Teable Tech Overview

Teable is a pnpm monorepo with a clear separation between a Next.js frontend and a NestJS backend — two apps, six shared packages.

Frontend — Next.js + Glide Data Grid

The web app is built with Next.js 16 and React 18. The star component is Glide Data Grid — a WebGL-rendered spreadsheet that virtualises both rows and columns, which is why 1,000,000-row tables feel like 100-row tables. TanStack Query handles server state; Zustand handles client UI state; FullCalendar powers the Calendar view; ECharts handles charts.

Real-time cell updates arrive over WebSocket via the ShareDB client — the same connection the backend uses to synchronise edits between users.

Backend — NestJS + Prisma + ShareDB

The NestJS server uses two ORM strategies:

  • Prisma manages the system schema — users, spaces, bases, permissions, metadata — via declarative migrations.
  • Kysely + Knex build dynamic SQL queries at runtime for user-defined tables, where the schema changes as users add fields and rows.

ShareDB runs the Operational Transformation engine that makes real-time collaboration work. When two users edit the same cell, OT ensures both edits are applied correctly instead of one overwriting the other.

BullMQ + Redis handle background jobs: formula recalculation, rollup updates, attachment processing, and email sending.

Field types

Teable supports a full range of column types: Text, Number, Date, Checkbox, Single/Multi Select, Attachments, Link (cross-table relationships), Formula, Lookup, Rollup, Rating, Currency, User, Auto Number, and more.

The Formula engine (in packages/formula) evaluates spreadsheet-style expressions with functions for string manipulation, date arithmetic, logical operations, and aggregates across linked records.

Self-Hosting Teable with Docker

Teable ships a clean standalone compose file. Three services, five minutes to running.

services:
  teable:
    image: ghcr.io/teableio/teable:latest
    restart: always
    ports:
      - '3000:3000'
    volumes:
      - teable-data:/app/.assets
    env_file:
      - .env
    environment:
      - TZ=${TIMEZONE}
    networks:
      - teable-standalone
    depends_on:
      teable-db:
        condition: service_healthy
      teable-cache:
        condition: service_healthy

  teable-db:
    image: postgres:15.4
    restart: always
    ports:
      - '42345:5432'    # exposes PG for direct SQL access
    volumes:
      - teable-db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    networks:
      - teable-standalone
    healthcheck:
      test: ['CMD-SHELL', "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 3s
      retries: 3

  teable-cache:
    image: redis:7.2.4
    restart: always
    volumes:
      - teable-cache:/data
    networks:
      - teable-standalone
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    healthcheck:
      test: ['CMD', 'redis-cli', '--raw', 'incr', 'ping']
      interval: 10s
      timeout: 3s
      retries: 3

networks:
  teable-standalone:
    driver: bridge

volumes:
  teable-data: {}
  teable-db: {}
  teable-cache: {}

Pair this with a .env file:

TIMEZONE=UTC

POSTGRES_DB=teable
POSTGRES_USER=teable
POSTGRES_PASSWORD=change_this_password

REDIS_PASSWORD=change_this_too

PUBLIC_ORIGIN=http://your-server-ip:3000
SECRET_KEY=a_long_random_string_change_this

PRISMA_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@teable-db:5432/${POSTGRES_DB}
PUBLIC_DATABASE_PROXY=your-server-ip:42345

BACKEND_CACHE_PROVIDER=redis
BACKEND_CACHE_REDIS_URI=redis://default:${REDIS_PASSWORD}@teable-cache:6379/0

Then:

docker compose up -d

Open http://your-server-ip:3000. The first account created becomes the admin.

Default credentials: None — you create the admin account on first load.

Services explained

Service Purpose
teable The full application — Next.js frontend + NestJS backend in one image
teable-db PostgreSQL 15 — stores all user data in real relational tables
teable-cache Redis 7 — session cache, job queue, real-time state

Port 42345 maps to PostgreSQL. This is intentional — it lets you connect any SQL client (psql, DBeaver, Metabase) directly to your Teable data without any API layer.

Conclusion

Teable occupies exactly the right spot in the no-code landscape: powerful enough for real data workflows, simple enough that non-developers can use it immediately, and built on standard PostgreSQL so you are never locked in.

The real-time collaborative editing via Operational Transformation, the WebGL grid that handles a million rows without slowing down, and the clean three-container Docker setup make it one of the most production-ready Airtable alternatives you can self-host today.

Alternatives worth comparing:

  • NocoDB — similar goal, stores data in its own format rather than native PG tables; easier initial setup
  • Baserow — Python/Django backend, strong plugin ecosystem, FOSS community edition
  • Grist — spreadsheet-database hybrid, Python formulas, unique dataflow model
  • Airtable — the original; excellent UX, cloud-only, per-seat pricing