❈Our backend-as-a-sevice is here - try Para Cloud for free!

A general-purpose backend for the cloud

Para is an open-source, stateless and schemaless backend with a REST API over any database, search index and cache.

Bring your own database. Batteries-included. No schema. No lock-in.

Para is built on several swappable layers. Start simple, then make it fit your requirements.

  • Feature iconFeature icon

    Schemaless objects

    Plain JSON in, plain JSON out. No migrations, no ORM ceremony. Works on key-value stores and traditional databases alike.

  • Feature iconFeature icon

    Three layers

    Every object is persisted, indexed and cached by default. Swap the database, the search engine and the cache independently.

  • Feature iconFeature icon

    Stateless scaling

    No sticky sessions, no node-local state. Scaling out just requires more nodes, not a re-architecture.

  • Feature iconFeature icon

    Multitenancy

    Each Para app is fully isolated and gets its own table, index and cache. Better efficiency and resource utilization.

  • Feature iconFeature icon

    Pluggable modules

    SQL, MongoDB, Cassandra or DynamoDB. Lucene or Elasticsearch. Caffeine or Hazelcast. Choose per deployment, not per product.

    sqlmongodbcassandradynamodbluceneelasticsearchcaffeinehazelcast
  • Feature iconFeature icon

    Built-in auth

    JWT, passwordless logins, LDAP, SAML and social login for all the major identity providers.

    jwtsocialpasswordlessldapsamloauth2
  • Feature iconFeature icon

    Webhooks

    Signed webhook payloads on object events. Wire Para into anything that speaks HTTP.

  • Feature iconFeature icon

    MCP server

    A built-in MCP server lets AI agents read and write your data directly, with the same permissions as any client.

Why not Supabase?

Para is a general-purpose backend, not a hosted database with extras. Different trade-offs, fewer lock-ins.

ParaSupabaseFirebaseParse
Databasesany (SQL, NoSQL, in-memory)PostgreSQL onlyproprietaryMongoDB
Data modelschemaless JSONschema + migrationsproprietary JSONschemaless JSON
Full-text searchyes, auto-indexingtedious, manual indexingtedious, manual indexingtedious, manual indexing
MCP server for AI agentsyesyesyesno
Self-host anywhereyesyesnoyes
LicenseApache-2.0Apache-2.0ProprietaryBSD-3 (community)

Para was designed to provide a straightforward developer experience and is optimized for LLM-based workflows and rapid prototyping. Para is a good fit if you ask yourself any of the following questions:

What if I don't want to manage a full PostgreSQL cluster?
You don't have to. Para runs on an embedded H2 database by default, so a single JAR file is a complete backend with no external database to install or tune. If you need more, you can switch to PostgreSQL, MySQL, MongoDB or another store through a plugin and one configuration property. On Para Cloud, all of this is managed for you.
What if my schema is not clarified yet or my data is too dynamic?
Para stores every record as a schemaless JSON object. There are no migrations, no fixed columns and no table definitions to update: you POST an object with any fields and the search index follows it. Add a field to one object and not to the next, or store different shapes under the same type, and Para accepts it without downtime.
What if I want to connect a no-code solution to my backend?
Para speaks plain HTTP and JSON. Any no-code tool that can send a REST request, such as Retool, Appsmith, n8n or Zapier, can create, read, update and delete objects with an API key or a JWT. Authentication, permissions and validation stay in Para, so the no-code layer only has to handle the screen.
What if I need to prototype an app quickly with a set-it-and-forget-it backend?
Start with java -jar para.jar and an embedded database. Users, social sign-in, permissions, full-text search and webhooks work on the first run, with no infrastructure to provision. When the prototype proves itself, the same API can move to a hosted or self-managed deployment without code changes.

Self-host in minutes

One JAR, one config file, any database. The quickstart has you persisting objects before your coffee cools.

Prefer containers? Run Para in Docker with one command:

$ docker run -it erudikaltd/para:latest_stable

Use the client you know

All Para clients share the same REST API. Create, read, update, and delete a user, then search users with one query.

import com.erudika.para.client.ParaClient;
import com.erudika.para.core.ParaObject;
import com.erudika.para.core.Sysprop;
import java.util.List;

ParaClient pc = new ParaClient("app:myapp", "secret");
pc.setEndpoint("http://localhost:8080");

Sysprop draft = new Sysprop();
draft.setType("user");
draft.setName("Ada");
ParaObject created = pc.create(draft);

ParaObject user = pc.read("user", created.getId());
user.setName("Ada Lovelace");
ParaObject updated = pc.update(user);

List<ParaObject> users = pc.findQuery("user", "*");
pc.delete(updated);

Maven · com.erudika:para-client

View SDK source
import { ParaClient, ParaObject } from "para-client-js";

const pc = new ParaClient("app:myapp", "secret");
pc.setEndpoint("http://localhost:8080");

const draft = new ParaObject();
draft.setType("user");
draft.setName("Ada");
const created = await pc.create(draft);

const user = await pc.read("user", created.getId());
user.setName("Ada Lovelace");
const updated = await pc.update(user);

const users = await pc.findQuery("user", "*");
await pc.delete(updated);

npm · para-client-js

View SDK source
from paraclient import ParaClient, ParaObject

pc = ParaClient("app:myapp", "secret")
pc.setEndpoint("http://localhost:8080")

draft = ParaObject(type_="user")
draft.name = "Ada"
created = pc.create(draft)

user = pc.read("user", created.id)
user.name = "Ada Lovelace"
updated = pc.update(user)

users = pc.findQuery("user", "*")
pc.delete(updated)

pip · paraclient

View SDK source
<?php
use Para\ParaClient;
use Para\ParaObject;

$pc = new ParaClient("app:myapp", "secret");
$pc->setEndpoint("http://localhost:8080");

$draft = new ParaObject(null, "user");
$draft->setName("Ada");
$created = $pc->create($draft);

$user = $pc->read("user", $created->getId());
$user->setName("Ada Lovelace");
$updated = $pc->update($user);

$users = $pc->findQuery("user", "*");
$pc->delete($updated);

Composer · erudika/para-client-php

View SDK source
using Para.Client;
using System.Collections.Generic;

var pc = new ParaClient("app:myapp", "secret");
pc.setEndpoint("http://localhost:8080");

var draft = new ParaObject();
draft.type = "user";
draft.name = "Ada";
ParaObject created = pc.create(draft);

ParaObject user = pc.read("user", created.id);
user.name = "Ada Lovelace";
ParaObject updated = pc.update(user);

List<ParaObject> users = pc.findQuery("user", "*");
pc.delete(updated);

NuGet · para_client_csharp

View SDK source
import ParaClient

let pc = ParaClient(accessKey: "app:myapp", secretKey: "")
pc.setEndpoint("https://your-para-host")

pc.signIn("password", providerToken: "[email protected]::PASSWORD", callback: { session in
    guard session != nil else { return }

    let draft = ParaObject()
    draft.type = "user"
    draft.name = "Ada"
    pc.create(draft, callback: { created in
        guard let created else { return }
        pc.read("user", id: created.id, callback: { user in
            guard let user else { return }
            user.name = "Ada Lovelace"
            pc.update(user, callback: { updated in
                guard let updated else { return }
                pc.findQuery("user", query: "*", callback: { users in
                    print("Found \(users?.count ?? 0) users")
                    pc.delete(updated)
                })
            })
        })
    })
})

Swift Package Manager · para-client-ios

View SDK source
import android.content.Context;
import android.util.Log;
import com.erudika.para.client.Listener;
import com.erudika.para.client.ParaClient;
import com.erudika.para.core.ParaObject;
import com.erudika.para.core.Sysprop;
import java.util.List;

void runExample(Context context) {
    ParaClient pc = new ParaClient("app:myapp", null, context);
    pc.setEndpoint("https://your-para-host");
    pc.signIn("password", "[email protected]::PASSWORD", new Listener<Sysprop>() {
        @Override public void onResponse(Sysprop session) {
            if (session == null) return;
            Sysprop draft = new Sysprop();
            draft.setType("user");
            draft.setName("Ada");
            pc.create(draft, new Listener<ParaObject>() {
                @Override public void onResponse(ParaObject created) {
                    if (created == null) return;
                    pc.read(Sysprop.class, created.getId(), new Listener<Sysprop>() {
                        @Override public void onResponse(Sysprop user) {
                            if (user == null) return;
                            user.setName("Ada Lovelace");
                            pc.update(user, new Listener<ParaObject>() {
                                @Override public void onResponse(ParaObject updated) {
                                    if (updated == null) return;
                                    pc.findQuery("user", "*", null, new Listener<List<ParaObject>>() {
                                        @Override public void onResponse(List<ParaObject> users) {
                                            Log.d("Para", "Users: " + (users == null ? 0 : users.size()));
                                            pc.delete(updated, null);
                                        }
                                    });
                                }
                            });
                        }
                    });
                }
            });
        }
    });
}

Gradle · com.erudika:para-client-android

View SDK source

Keep secret keys on trusted servers. Browser and mobile apps should leave the secret key blank, sign in, and use the permissions granted to that user.

Prefer a managed BaaS?

Para Cloud is our fully managed backend-as-a-service — hosted, patched and production-ready.

  • Managed hosting by the makers of Para
  • Automatic updates, backups and monitoring
  • Basic support included
Explore Para Cloud

Free plan available · 25€ / app / month