Soul: Automatic REST and Realtime APIs for SQLite
🕉 Soul | Automatic SQLite RESTful and realtime API server | Build CRUD APIs in minutes!
At a glance
- What is it?
- Soul is a Node.js CLI that exposes an SQLite database through REST and WebSocket endpoints. It suits developers who need a small CRUD API quickly, but it requires accepting its Node.js runtime and database-backed deployment model.
- Who is it for?
- Adopt Soul for prototypes, internal tools, or small applications when a SQLite database can be the system of record and automatic CRUD endpoints are more useful than a separately designed API layer. Do not choose it solely for multi-service, high-availability, or heavily governed deployments without verifying its operational model.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 50 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Soul's SQLite API boundary
Soul solves a narrow but practical problem: turning a SQLite database into an HTTP and WebSocket server without first writing a complete application layer. The README describes it as a SQLite REST and realtime server, and the repository packages it as `soul-cli`. The target audience is developers who already have a SQLite file and need database-backed endpoints quickly, such as for a prototype, a local service, or a small application.
The command requires a database path through `-d` or `--database`. That path can be a file such as `sqlite.db`, or it can be `:memory:`. The server exposes REST endpoints on `http://localhost:8000` and a WebSocket server on `ws://localhost:8000` in the documented default setup. This is an automatic API surface over the selected database, not a general-purpose application framework in which the API contract is designed first.
That distinction matters. Soul is most useful when CRUD behavior and direct table access are acceptable. It is a poor fit when the service must mediate every database field, support complex relational workflows, or coordinate multiple durable backends. The repository describes automatic CRUD APIs as the central use case, so the design centers on making an existing database immediately reachable rather than providing a separate schema abstraction.
REST, WebSocket, and runtime architecture
The visible stack is an Express 5 application backed by `better-sqlite3`, with `ws` providing WebSocket support. The package entry point is `src/server.js`, and the executable name is `soul`. The CLI accepts the database and port, while the package scripts run the same server through `npm start`.
The REST side is organized around database resources. The README directs users to `/api/tables` to list tables in the connected database and points to runtime API documentation at `/api/docs`. A separate `docs/api-examples.md` file contains endpoint examples, while `docs/ws-examples.md` contains WebSocket examples. Those files are the appropriate places to inspect the exact request paths, payload formats, and event behavior before designing an application around Soul.
The server also includes middleware-oriented dependencies for CORS, cookie parsing, Helmet, request body parsing, rate limiting, Joi validation, and logging. That gives the project a conventional Node.js HTTP shape, but the repository description does not claim that it replaces an API gateway or application-specific service layer. The database remains the central resource, and the WebSocket endpoint is intended to provide realtime access rather than a separate message broker.
The API documentation is available only while the server is running. For an initial review, start the server against an existing database, open `/api/docs`, and compare the generated endpoint set with `docs/api-examples.md`. The README does not document a separate migration workflow in the excerpt, so schema creation or migration should not be assumed to be part of the startup command.
Installing Soul and starting the first server
Soul requires Node.js `22.x`, `23.x`, `24.x`, `25.x`, or `26.x`, according to the `engines` field in `package.json`. The `better-sqlite3` dependency is the reason the README gives for the Node.js 22 minimum. The documented npm installation is:
npm install -g soul-cliThis installs the `soul` command globally. Once the command is available, start it with a SQLite file and port:
soul -d sqlite.db -p 8000The README states that this starts the REST API at `http://localhost:8000` and the WebSocket server at `ws://localhost:8000`. A reader can confirm that the HTTP process is reachable by requesting the table listing:
curl http://localhost:8000/api/tablesAccording to the README, the response should contain the tables in `sqlite.db`. If the database file does not yet exist or has no tables, the documentation does not state what this endpoint returns, so the response should be interpreted as a connectivity and table-discovery check rather than a schema-creation command.
For a containerized start, the README includes a Dockerfile based on Node.js 22 Alpine, installs `python3` and `build-base`, runs `npm ci`, and starts with `npm start`. The fallback build packages are documented for platforms where a prebuilt native binary is unavailable. The documented API documentation URL is `http://localhost:8000/api/docs`.
Authentication, permissions, and browser configuration
Soul has an optional authentication mode that adds signup, login, authorization, and user-management commands. The documented startup example enables it with `-a`, supplies a JWT secret through `--ts`, sets access and refresh token durations, and creates an initial user with `--iuu` and `--iup`:
soul -d foobar.db -a --ts=<your_jwt_secret_value> --atet=4H --rtet=3D --iuu=john --iup=<your_password>The access-token duration accepts values such as `60M`, `5H`, and `1D`. The refresh-token duration is configured separately with `--rtet`. The README says the token secret should be kept, because losing it can lock users out when the server restarts. It also recommends a secret of at least 10 characters, though that recommendation does not replace choosing a deployment-appropriate secret.
Authentication is optional, which means database exposure depends on how the command is launched. The project includes rate-limit options, including `--rate-limit-enabled`, and CORS accepts a comma-separated origin list through `--cors`. The README explicitly warns that the default or wildcard value disables cookie-based credentials on cross-origin requests. An authenticated frontend on another origin therefore needs an explicit origin list and compatible cookie settings.
The `.env.sample` shows configuration keys such as `CORE_PORT`, `CORS_ORIGIN_WHITELIST`, `AUTH`, `COOKIE_SAMESITE`, `COOKIE_SECURE`, `RATE_LIMIT_ENABLED`, `DB`, `ACCESS_TOKEN_EXPIRATION_TIME`, `REFRESH_TOKEN_EXPIRATION_TIME`, `INITIAL_USER_USERNAME`, `INITIAL_USER_PASSWORD`, `TOKEN_SECRET`, and `START_WITH_STUDIO`. The README documents custom environment files with `--env`, but requires an absolute path and does not allow relative paths.
User administration and operational trade-offs
The `updatesuperuser` command provides a documented path for changing a user's password and promoting or demoting the superuser role. The syntax includes a user ID and either a `password` assignment or an `--is_superuser` value:
soul -d foobar.db updatesuperuser --id=1 password=<new_password_for_the_user>
soul -d foobar.db updatesuperuser --id=1 --is_superuser=true
soul -d foobar.db updatesuperuser --id=1 --is_superuser=falseThis is useful when the database already exists and an administrator needs a direct maintenance operation. It also reveals a practical constraint: administration is performed through the CLI and the same database file, so backup and access-control procedures remain the operator's responsibility. The README does not document a dashboard workflow for all of these tasks, although Soul Studio can be started with `--studio`.
The native `better-sqlite3` dependency also changes deployment considerations. The supported Node.js versions are explicit, and the Docker example includes native build tools as a fallback. A runtime that is not listed in `engines`, a platform without a compatible binary, or a missing compiler toolchain can turn a one-command npm install into a platform-specific build problem. The repository's MIT license permits use and modification under its terms, but license status does not answer operational questions such as backup retention, secret rotation, or database concurrency.
Soul compared with a manually designed API
The closest practical alternative is a conventional Node.js API written with Express and a deliberately designed persistence layer. That approach still can use SQLite and can use the same broad package families, but its API contract is defined by application code rather than inferred from a database-oriented server workflow.
The difference is control. A hand-written service can validate a request, map it to a domain object, apply authorization rules per endpoint, and keep database columns private. Soul's documented value is faster CRUD exposure, with optional auth mode and WebSocket access available from the CLI. That makes it a better fit when the database is a trusted internal boundary and the immediate goal is to obtain working endpoints.
The alternative is preferable when clients need stable, purpose-specific resources, when the public schema must differ from storage, or when operations need application-specific transactions and error contracts. Soul is also less suitable as a comparison point for a horizontally distributed API service: the README describes a SQLite file and a single local database process, not a replicated multi-node service.
A sensible adoption decision therefore depends on the endpoint contract and deployment topology. Inspect `/api/docs`, `docs/api-examples.md`, and `docs/ws-examples.md` first. If those endpoints match the intended client behavior, the CLI can remove substantial setup. If they do not, writing a separate API layer may cost more initially but avoid rewriting access rules later.
Editorial conclusion
Adopt Soul for prototypes, internal tools, or small applications when a SQLite database can be the system of record and automatic CRUD endpoints are more useful than a separately designed API layer. Do not choose it solely for multi-service, high-availability, or heavily governed deployments without verifying its operational model. Check Node.js compatibility, authentication configuration, CORS behavior, and the available API examples before committing.
Frequently asked questions
How do I install and run Soul for a SQLite database?
Install the npm package with `npm install -g soul-cli`, then run `soul -d sqlite.db -p 8000`. The README says this starts REST at `http://localhost:8000` and WebSocket at `ws://localhost:8000`.
What Node.js versions does Soul require?
Soul requires Node.js `22.x`, `23.x`, `24.x`, `25.x`, or `26.x`. The README attributes this requirement primarily to the `better-sqlite3` dependency.
How can I enable authentication in Soul?
Pass `-a` with `--ts`, `--atet`, `--rtet`, `--iuu`, and `--iup`. The README documents JWT-based access and refresh tokens and an initial user, but also warns that the token secret must be retained.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/thevahidal-soul)Was this useful?