Home

Awesome

<p align="center"> <a href="https://thin.dev/" target="_blank"> <img src="header.png" /> </a> </p> <h1 align="center"><b>Thin Backend</b></h1> <p align="center"> Instant API for your Postgres DB <br /> <a href="https://thin.dev/"><strong>thin.dev ยป</strong></a> </p>

Thin Backend is a blazing fast, universal web app backend for making realtime single page apps.

Instead of manually writing REST API endpoints or GraphQL resolvers, use a Thin Backend server to automatically get a fully featured API backend on top of your Postgres DB. Thin exposes high level functions to create, read, update and delete database record.

<p align="center"> <img src="https://thin-backend-prod.s3.amazonaws.com/public-static/github/demo4.gif"/> </p>

Code Examples

This example shows a simple CRUD example for building a Todo app with Thin:

import { useQuery, query, createRecord, updateRecord, deleteRecord, Task } from 'ihp-backend';

function Tasks() {
    // `useQuery` automatically triggers a re-render on new data
    const tasks = useQuery(query('tasks').orderBy('createdAt'));

    return <div>
        <h1>Tasks</h1>
        {tasks.map(task => <Task task={task} key={task.id} />)}
    </div>
}

interface TaskProps {
    task: Task; // <- The `Task` type is provided by Thin, auto-generated from the database schema
}
function Task({ task }: TaskProps) {
    const handleEdit = () => {
        const patch = {
            title: window.prompt('New Title:') || task.title
        };

        // `updateRecord` already updates the UI state (e.g. the <Tasks /> component above)
        // even before the server completed the operation.
        updateRecord('tasks', task.id, patch);
    }

    const handleDelete = () => {
        // `deleteRecord` already hides the record from the UI state
        // even before the server completed the operation.
        deleteRecord('tasks', task.id);
    }

    return <div onDoubleClick={handleEdit}>
        {task.title}

        <button onClick={handleDelete}>delete</button>
    </div>
}

function AddTaskButton() {
    const handleClick = () => {
        const task = {
            title: window.prompt('Title:')
        };

        // `createRecord` already shows the new task in the UI
        // even before the server completed the operation.
        createRecord('tasks', task);
    }

    return <button onClick={handleClick}>Add Task</button>
}

function App() {
    // No need for redux or other state management libs
    // `useQuery` automatically triggers a re-render on new data
    return <div>
        <Tasks />
        <AddTaskButton />
    </div>
}

Try on Vercel

Top-notch Autocompletion

The TypeScript definitions not only provide safety, they also provide really nice autocompletion.

Feature Overview

Documentation

You can find extensive documentation on the Thin Backend website.

Getting Started

Learn how to get started in the Getting Started Guide

You can also self-host Thin Backend.

Example Apps

You can find some example apps here:

Community

Questions, or need help? Join our Thin Community

Contributing

We are happy to merge your pull requests!๐Ÿ˜„

See CONTRIBUTING.md for more info.