Skip to content

Quick Start

Get a FraiseQL GraphQL API running in 5 minutes. This guide assumes you have a PostgreSQL database with tables already set up. For the full workflow including database setup with 🍯 Confiture, see Your First API.

  • PostgreSQL database with tables created
  • Your preferred schema language installed (Python 3.10+, Node.js 18+, or Go 1.21+)

FraiseQL is a Rust binary. Install it once, use it from any project regardless of language.

Terminal window
# Install script (macOS / Linux)
curl -fsSL https://fraiseql.dev/install.sh | sh
# Homebrew (macOS)
brew install fraiseql
# From source (requires Rust toolchain)
cargo install fraiseql

Verify:

Terminal window
fraiseql --version

The schema SDK lets you define GraphQL types in your preferred language using decorators or structs.

Terminal window
uv add fraiseql
# or: pip install fraiseql

Create SQL views that follow the .data JSONB pattern. Each view has an id column and a data column:

db/schema/02_read/v_user.sql
CREATE VIEW v_user AS
SELECT
u.id,
jsonb_build_object(
'id', u.id::text,
'name', u.name,
'email', u.email,
'created_at', u.created_at
) AS data
FROM tb_user u;
db/schema/02_read/v_post.sql
CREATE VIEW v_post AS
SELECT
p.id,
jsonb_build_object(
'id', p.id::text,
'title', p.title,
'content', p.content,
'author', vu.data
) AS data
FROM tb_post p
JOIN tb_user u ON u.pk_user = p.fk_user
JOIN v_user vu ON vu.id = u.id;

Apply these views to your database (or use confiture build — see 🍯 Confiture).

Create a file called schema.py:

schema.py
import fraiseql
from fraiseql.scalars import ID, Email, DateTime
@fraiseql.type
class User:
"""A user in the system."""
id: ID
name: str
email: Email
created_at: DateTime
@fraiseql.type
class Post:
"""A blog post."""
id: ID
title: str
content: str
author: User
published: bool

Create fraiseql.toml with your database connection string:

fraiseql.toml
[project]
name = "quickstart"
version = "0.1.0"
[database]
type = "postgresql"
url = "postgresql://localhost:5432/mydb"
[server]
port = 8080
host = "127.0.0.1"
Terminal window
# Compile the mapping between your types and SQL views
fraiseql compile
# Start the server
fraiseql run

You should see:

✓ Compiled 2 types → mapped to SQL views
✓ Built query executor
→ GraphQL API running at http://localhost:8080/graphql

Open your browser to http://localhost:8080/graphql or use curl:

Terminal window
curl -s -X POST http://localhost:8080/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ users { id name email } }"}' | jq .

Response:

{
"data": {
"users": [
{
"id": "1",
"name": "Alice",
"email": "alice@example.com"
}
]
}
}

If a query references a field that doesn’t exist, FraiseQL returns a structured error:

{
"errors": [
{
"message": "Cannot query field 'phone' on type 'User'",
"locations": [{ "line": 1, "column": 28 }]
}
]
}
  1. SQL views created — You wrote views following the .data JSONB pattern
  2. Schema compiled — FraiseQL mapped your GraphQL types to those SQL views
  3. Query executor built — Pre-compiled query paths for each type
  4. API served — Every GraphQL query resolves to a single SQL statement

No resolvers. No N+1 problems. No generated SQL you can’t read.

Query the same schema — users, posts, comments, tags — against a live FraiseQL server backed by real PostgreSQL. No account required.

FraiseQL Demo API

Try the schema from this guide against a live server.

Loading Apollo Sandbox...

This sandbox uses Apollo Sandbox (the same GraphQL IDE as fraiseql serve). Your queries execute against the endpoint below. No data is sent to Apollo. Learn more about privacy →