Skip to content

ROW A · OPEN-SOURCE SEATING SDK

Design the venue.Price every seat.Sell from one link.

OpenSeat is a free, open-source seating layout designer and seat-selection SDK.

concert-hall.json · 282 seats
LIVE · 45 sold
A real OpenSeat layout rendered with layoutToSvg at build time. Buyer activity is simulated.
  • VIP ₹1,499
  • Stalls ₹499
  • Balcony ₹299
  • Held
  • Sold
  • Selected
npm i @openseat/react @openseat/core @openseat/adapter-rest konva react react-dom

first npm release pendingFree · MIT · no account or API keyAPI reference

  • Free · MIT
  • 7 packages
  • TypeScript
  • React 18.2+ / 19
  • Strict CSP, no eval

Built for every kind of venue

Built for every kind of venue · 45 venues · 104 setups

  • Cricket ground
  • Football ground / stadium
  • Field hockey stadium
  • Athletics stadium (400 m track)
  • Tennis centre
  • Badminton hall
  • Aquatic centre / pool
  • Stadium (multi-purpose)
  • Indoor sports arena
  • Auditorium
  • Theatre / performing arts centre
  • Concert hall
  • Amphitheatre / open-air theatre
  • Open ground
  • Lawn / garden venue
  • Park
  • Festival ground
  • Rooftop event space
  • Waterfront / lakeside space
  • Expo / exhibition hall
  • Convention centre
  • Trade fair hall
  • Banquet hall
  • Nightclub / lounge
  • Party hall
  • Farmhouse (lawn)
  • University campus ground
  • Lecture hall / theatre
  • Seminar hall
  • Student centre
  • Multipurpose hall
  • E-sports arena
  • Gaming centre
  • Karting track
  • Adventure park
  • Community hall
  • Art centre (gallery + studio)
  • Cultural centre
  • Hotel ballroom
  • Resort (pool deck and lawn)
  • Banquet garden / lawn
  • Warehouse
  • Mall atrium
  • Industrial space
  • Hangar

THE IDEA

One document, three steps: design, price, sell.

A venue in OpenSeat is one validated JSON layout. Organisers shape it, your price list colours it, and buyers book from it. Nothing about prices or bookings is baked into the drawing, so one layout serves every show.

ROW A · DESIGN

Draw the venue, or start from a real one.

Pick an auditorium, a banquet hall, an open ground or a cricket ground, type how many people are coming, and OpenSeat fits rows, tables, booths or standing areas to that number. Then adjust anything: rows, curves, aisles, tables, booths, stages and labels, with undo, snapping and a layers panel.

Typed 400 → fits 408 seatsGenerate a section live
curve 20snap 15°⌘Z undo

ROW B · PRICE

Give every part of the hall a ticket type.

VIP ₹1,499, Stalls ₹499, Balcony ₹299: assign ticket types to a section, a row or a single seat. Prices stay with the event, not the drawing, and show in the legend, the seat label and the buyer's total.

VIP ₹1,499Stalls ₹499Balcony ₹299

categoryPrices → legend, labels, totals

ROW C · SELL

Buyers pick seats on their phone.

The ticket page opens on the whole venue; one tap zooms in, the next picks a seat. Seats are held for 10 minutes with a countdown while the buyer pays, and sold seats turn grey for everyone.

Holds are timed by your server. The OpenSeat server prevents double booking inside Postgres itself.

  • Available
  • Held
  • Sold
  • Selected
SummaryHeld for 9:29

2 × VIP

Row B · Seats 7–8

Total₹2,998

Frontend-first SDK

Your app, your backend, your rules.

OpenSeat brings no backend, database or payment provider. Seven typed packages draw the map, run the designer and apply selection rules in the browser; your backend owns inventory, holds and payments through typed adapter contracts or the optional REST adapter.

Optional · OpenSeat server

Or run the open-source server.

Fastify and Postgres 16, free to self-host (public image coming soon): organiser accounts, events with short links, holds and bookings with double-booking prevention in the database, live availability, a bookings list with CSV export, and payments at the venue, by UPI reference or through Razorpay.

WHAT'S INSIDE

Everything a seat map needs, nothing it doesn't.

Seven focused packages: a layout schema, a canvas renderer, React components, a full designer, booking rules, a REST adapter and design tokens.

Sections · parametric

Parametric sections

Rows × seats per row with curvature, ragged rows, stagger, aisles and row and seat numbering (letters, numbers, roman numerals, odd/even, skipped labels). Change any parameter and the section regenerates while every seat keeps its ID.

Try the generator
Stage
60 seats · IDs keptD5 → D5

Generators · arena

Arena generator

arenaPreset("hockey") builds a complete 9,758-seat NHL-style bowl in one call, in about 36 ms. Basketball, concert-in-the-round and football presets too. Every section stays editable.

See the code

9,758

seats in one call · about 36 ms

arenaPreset("hockey")

Templates

104 venue templates

45 venues in 10 categories, from seminar halls to stadiums. Fitted to your audience, with wheelchair spaces, Not for sale places and suggested prices in ₹. Every setup can also be built as sections only.

Browse templates

104setups

45 venues
10 categories

Zones · quantity

Zone maps

Sell sections and drawn zones by quantity instead of seat by seat: pastel tier blocks, upper-case names, an Available / Sold out legend and a phone-friendly quantity picker.

Stage
Fan pit · ₹1,998
2

Performance

Fast

2,000 seats render in about 15 ms and redraw in under 3 ms per frame.

~15ms first render

First render≈ 15 ms
Redraw per frame (mean)2.5 ms

2,000 seats · bar = one 60 fps frame (16.7 ms)

Buyers · booking map

Buyer booking map

Section overview with click-to-zoom, statuses from your backend, selection rules (ticket limits, single category, no stranded seats), whole tables and standing areas as units, holds with a server-timed countdown, keyboard navigation, screen-reader announcements and an accessible seat list.

Book a seat in the demo
Stage
Held for 10 minutes
  • Ticket limit: max 8
  • Single category
  • No stranded seats
  • Whole tables and standing areas
  • Keyboard and screen reader

Export

Export anything

Byte-stable JSON, standalone SVG (also in Node) and PNG, including Instagram post and story sizes.

  • JSONbyte-stable
  • SVGalso in Node
  • PNGany scale
  • 1080 × 1080Instagram post
  • 1080 × 1920Instagram story

Inventory

Inventory manifest

Every save carries a flat manifest of what is sellable. diffManifests tells your backend which seat IDs were added, removed, moved or relabelled.

diffManifests(prev, next)

+ 12 added− 3 removed4 moved2 relabelled

example output · seat IDs per change

Schema

Validated schema

A documented, versioned layout schema with structured errors, size limits for untrusted input, migrations and deterministic JSON.

validateLayout(untrusted)

→ { valid: true }✓

250,000 objects64 KB metadata20,000 seats / sectionmigrations

TEMPLATES

Start from a venue you already know.

Search by venue or by event (“farewell banquet”, “dj night”, “convocation”), type your expected audience, and get a layout that fits.
  • Schematic of the annual day / cultural fest template for a auditorium: 664 seats · 12 sections

    Auditorium

    Annual day / cultural fest

    664 seats · 12 sections

    performance.auditorium.annual-day

  • Schematic of the convocation / graduation template for a auditorium: 927 seats · 357 held for graduands

    Auditorium

    Convocation / graduation

    927 seats · 357 held for graduands

    performance.auditorium.convocation

  • Schematic of the banquet rounds + dance floor template for a banquet hall: 31 tables · 248 seats

    Banquet hall

    Banquet rounds + dance floor

    31 tables · 248 seats

    social.banquet-hall.rounds-dance

  • Schematic of the concert / pro-night template for a open ground: 5,276 standing · 10 booths

    Open ground

    Concert / pro-night

    5,276 standing · 10 booths

    outdoor.open-ground.concert

  • Schematic of the fest night on the outfield template for a cricket ground: 8,241 capacity · 16 booths

    Cricket ground

    Fest night on the outfield

    8,241 capacity · 16 booths

    sports.cricket.fest-night

  • Schematic of the mega college fest template for a stadium (multi-purpose): 14,117 capacity · 40 booths

    Stadium (multi-purpose)

    Mega college fest

    14,117 capacity · 40 booths

    sports.stadium.mega-fest

  • Schematic of the tech fest expo template for a expo / exhibition hall: 64 booths · 192 seats

    Expo / exhibition hall

    Tech fest expo

    64 booths · 192 seats

    exhibition.expo-hall.tech-fest

  • Schematic of the cultural night template for a amphitheatre / open-air theatre: 1,167 seats

    Amphitheatre / open-air theatre

    Cultural night

    1,167 seats

    performance.amphitheatre.cultural-night

  • Schematic of the proscenium drama template for a theatre / performing arts centre: 879 seats

    Theatre / performing arts centre

    Proscenium drama

    879 seats

    performance.theatre.proscenium

  • Schematic of the open mic / stand-up night template for a student centre: 265 capacity · 24 tables

    Student centre

    Open mic / stand-up night

    265 capacity · 24 tables

    academic.student-centre.open-mic

  • Schematic of the tournament finals template for a e-sports arena: 990 capacity

    E-sports arena

    Tournament finals

    990 capacity

    specialised.esports-arena.finals

  • Schematic of the gala dinner / prom template for a hotel ballroom: 45 tables · 450 seats

    Hotel ballroom

    Gala dinner / prom

    45 tables · 450 seats

    hospitality.hotel-ballroom.gala

Capacities are the default build, before you type a target. Planning estimates aligned to NBC Part 4 occupant loads; check local fire and building codes.

Browse all 104 in the playground

FOR DEVELOPERS

A seat map in your React app, on your API.

Install the parts you need. BookingMap draws the venue and handles selection; useInventory keeps statuses live through an adapter; your server decides what is really held and sold.
Venue.tsx
import { useState } from "react";
import { createLayout, generateStraightRows } from "@openseat/core";
import { createRestAdapter } from "@openseat/adapter-rest";
import { BookingMap, useInventory } from "@openseat/react";

const layout = createLayout({ id: "hall", name: "Main hall", width: 1000, height: 800 });
layout.objects = generateStraightRows({
  idPrefix: "stalls",
  rowCount: 10,
  seatsPerRow: 20,
  origin: { x: 100, y: 100 },
  seatSpacing: 28,
  rowSpacing: 32,
  aisleAfter: [10],
}).objects;

const api = createRestAdapter({ baseUrl: "https://api.example.com" });

export function Venue() {
  const { statuses } = useInventory(api, "show-2026-11-20");
  const [selection, setSelection] = useState<readonly string[]>([]);
  return (
    <BookingMap
      layout={layout}
      statuses={statuses}
      selectedSeatIds={selection}
      onSelectionChange={(next) => setSelection(next)}
      rules={{ maxSeats: 8, preventOrphans: true }}
    />
  );
}
OpenSeat package architecture: editor and react build on renderer-konva and booking, which build on core and theme-default; adapter-rest connects booking to your backend or the OpenSeat server.YOUR BACKENDorOPENSEAT SERVEReditorLayoutEditorreactBookingMap · hooksrenderer-konvacanvas · layoutToSvgbookingrules · holdstheme-defaulttokenscoreschema · generatorsadapter-restBookingAdapter
@openseat/* · ES modules · strict CSPbuyer pages never load the editor
Truth lives on your server. A seat shown as available can be taken a moment later. Only a successful hold from your server reserves it.

BY THE NUMBERS

Measured, not promised.

venue setups
104
venues in 10 categories
45
first render, 2,000 seats
~15 ms
redraw per frame, 2,000 seats
< 3 ms
seats in one arenaPreset("hockey") call
9,758
to generate that arena
~36 ms
parallel holds on one seat succeed (the rest are refused)
1 of 50
unsafe-eval needed (strict CSP)
0

Benchmarks: Apple M5, headless Chromium / Node 26, Oct 2026. The double-booking test runs against the OpenSeat server.

FOR ORGANISERS

From WhatsApp link to booking list.

Design on a laptop, check on a phone, share one link. With the free OpenSeat server, every booking lands in one place.

  • Share link and QR code

    Share with buyers gives you a link, a ready-made WhatsApp invite message and a QR code for the poster. With the OpenSeat server, each event gets a short link /e/CODE with a preview for WhatsApp and SMS.

  • Phone-first ticket page

    Opens on the whole venue, first tap zooms in, a sticky bar shows the total, checkout opens as a bottom sheet. No app or sign-in for buyers.

  • UPI, pay at venue or Razorpay

    Pay at the venue or by UPI with the buyer's transaction reference by default; Razorpay Payment Links when you add your keys.

  • Bookings list and CSV

    Search, export to CSV, mark paid, cancel, erase.

  • Live availability

    Seats update for every buyer over server-sent events.

  • Accessible seating

    Mark wheelchair spaces; buyers find them with Show accessible seats. Block seats for judges and chief guests as Not for sale.

Free to self-host: the OpenSeat server gives you organiser sign-in, Publish and share (short link, QR code, WhatsApp text) and a Bookings page. There are no paid plans. The public server image is coming soon; until then, your developer can embed the booking map in your own site.

Illustration: a buyer's phone showing the ticket page with two held seats and a checkout bar, next to the share card with a QR code, the payment options and a bookings CSV export.

SECURITY & RELIABILITY

Built so two people never buy the same seat.

  • Double booking stopped by Postgres

    Holds claim seats with one conditional UPDATE on locked rows; a sold seat is unique per event; confirming twice returns the same booking. Tested with 50 parallel holds on one seat: exactly one wins.

  • Strict Content-Security-Policy

    No inline scripts, no eval, no third-party origins. Validation runs jitless.

  • Untrusted input has limits

    250,000 objects per layout, 64 KB of metadata, 20,000 seats per section, refused __proto__ keys.

  • Buyer data retention

    Names, phones and UPI references are erased 180 days after the event by default.

  • Rate limits and CSRF

    Per-route rate limits, an Origin check on every change, secure __Host- cookies.

  • Your rules, enforced twice

    The browser checks limits for a smooth experience; your server checks them again.

FREE · OPEN SOURCE · MIT

Free. Open source. MIT.

No plans, no per-ticket fees, no sign-up. OpenSeat is an SDK you install and own: use it, change it and ship it, including in commercial products.

Admit everyone · any venue

₹0forever

to OpenSeat, for every seat you sell. The ticket prices are yours to set.

What's free

  • The whole SDKSeven @openseat packages, TypeScript and ES modules.
  • The designerLayoutEditor, embedded in your organiser pages.
  • The booking mapBookingMap with holds, a countdown and an accessible seat list.
  • 104 venue templates45 venues, fitted to the audience you expect.
  • ExportJSON, SVG and PNG. SVG even renders in Node.
  • The OpenSeat serverFree to self-host on Postgres. Public image coming soon.

Taking payments online? Gateway fees are charged by your gateway, not OpenSeat.

How to start

  1. 01

    Install from npm

    The packages you need, plus konva and React as peers.

    npm i @openseat/react @openseat/core @openseat/adapter-rest konva react react-dom

    first npm release pendingthe command works once it ships

  2. 02

    Embed the map

    Drop BookingMap into any React page for buyers, and LayoutEditor into your organiser dashboard.

  3. 03

    Connect your backend

    Implement four BookingAdapter methods, or point createRestAdapter at an API that follows the reference REST contract. Your server owns holds and payments.

FAQ

Questions, answered.

More in the developer guide and the API reference.

A free, open-source (MIT) seating layout designer and seat-selection SDK that developers add to their own sites. Organisers draw or pick a venue, set ticket types and prices, and buyers choose seats on a map.

Yes. OpenSeat has no paid plans and charges no fees, per ticket or per month. All seven packages are MIT licensed: use, modify and ship them, including commercially. The ticket prices you set for your events are yours.

Start building →

Yes, from the public npm registry: npm i @openseat/react @openseat/core @openseat/adapter-rest konva react react-dom. The first npm release is still pending, so the command works once the packages are published.

Quickstart →

On this site. The API reference is generated from the packages' TypeScript types, so it matches the code you install. It covers all seven packages and the reference REST contract.

Open the API reference →

You need a server that owns holds and bookings: the API you already have, or the OpenSeat server. The SDK talks to it through typed adapter contracts or the optional REST adapter. The OpenSeat server (Fastify and Postgres) is free to self-host; its public image is coming soon.

Your backend, or ours →

No. OpenSeat is an SDK you embed in your own site, connected to your own backend or a self-hosted OpenSeat server (public image coming soon). There are no accounts, plans or fees.

Only a successful hold from the server reserves a seat. The OpenSeat server enforces holds, sales and ticket limits inside Postgres, so they hold even with several processes.

Yes. The ticket page is phone-first: it opens on the whole venue, the first tap zooms in, and checkout opens from the bottom of the screen.

Yes. Zones and standing areas sell by quantity, booths by ID, and banquet tables can be sold only as a whole.

With the OpenSeat server: pay at the venue or UPI with a transaction reference by default, and Razorpay online payments when you add your keys. Gateway fees are charged by the gateway.

2,000 seats render in about 15 ms; a 9,758-seat arena generates in about 36 ms. Very large maps (10,000 seats) currently pan at about 30 fps when fully zoomed out.

The booking map has keyboard navigation, screen-reader announcements, an accessible seat list and a Show accessible seats filter; organisers can mark wheelchair and companion seats.

ROW Z · YOUR TURN

Draw your first venue in minutes.

Open the live demo, design a hall, price it and book a seat yourself. Then install the free SDK and put it in your own ticketing site.