A lightweight, self-hosted web interface for managing SQLite databases. Written in Go, it provides a robust, CGO-free solution for inspecting and modifying SQLite files through a modern, responsive web browser interface.
Designed for simplicity and portability, Tabulita serves as both a graphical user interface and a JSON API endpoint, making it an ideal tool for embedded systems, rapid prototyping, or lightweight database administration.
- Database Management: Create, rename, copy, and drop tables.
- Schema Modification: Add, rename, and remove columns dynamically.
- Data Manipulation: Full CRUD (Create, Read, Update, Delete) support for table rows.
- Advanced Viewing: Integrated search and column sorting (ASC/DESC).
- Security: Optional HTTP Basic Authentication.
- Responsive UI: A clean interface built with Beer CSS and Material Design icons.
- Zero Dependencies: Built with
modernc.org/sqlite, requiring no CGO or external C libraries. It compiles to a single static binary.
To build the application, clone the repository and run the provided Makefile:
git clone https://github.com/eja/tabulita.git
cd tabulita
make tabulitaThis will generate the binary in the build/ directory. For a statically linked binary suitable for minimal environments, run:
make staticStart the server by pointing it to the directory containing your SQLite files:
./build/tabulita -file-path /path/to/your/databases| Flag | Default | Description |
|---|---|---|
-file-path |
. |
Path to the SQLite database or a directory of db files |
-web-host |
localhost |
The interface to bind the web server to. |
-web-port |
35248 |
The port to serve the application on. |
-web-path |
/tabulita/ |
The HTTP path prefix for the interface. |
-web-auth |
None | Basic Auth credentials in user:password or Base64 format. |
-log |
false |
Enable verbose logging. |
-log-file |
None | Path to a file for log output. |
Once running, access the interface at http://localhost:35248/tabulita/.
Tabulita exposes a single endpoint (defaulting to /tabulita/) that accepts POST requests containing a JSON payload. The server determines the operation based on the action field.
All API responses follow this format:
{
"success": true,
"data": { ... },
"error": "Error message if success is false"
}Retrieves rows from a specific table, with optional searching and sorting.
Request:
{
"action": "list-rows",
"table": "users",
"start": 0,
"stop": 19,
"query": "search_term_optional",
"sort_col": "username",
"sort_dir": "ASC"
}- start/stop: The zero-based index range for pagination.
- sort_dir: "ASC" or "DESC".
Response Data:
{
"tableName": "users",
"columns": [{"name": "id", "type": "INTEGER"}, ...],
"rows": [
{ "id": "1", "values": ["1", "John Doe", "admin"] }
],
"start": 0,
"stop": 19,
"totalRows": 154,
"totalPages": 8
}Lists all non-system tables in the database.
{ "action": "list-tables" }Creates a new table with a primary key column.
{
"action": "create-table",
"table": "new_table_name",
"col_name": "id",
"col_type": "INTEGER PRIMARY KEY AUTOINCREMENT"
}Renames an existing table.
{
"action": "rename-table",
"table": "old_name",
"new_name": "new_name"
}Creates a copy of a table (schema + data).
{
"action": "copy-table",
"table": "source_table",
"new_name": "destination_table"
}Adds a new column to an existing table.
{
"action": "add-column",
"table": "users",
"col_name": "email",
"col_type": "TEXT",
"is_not_null": false
}Renames a column in a table.
{
"action": "rename-column",
"table": "users",
"col_name": "old_col_name",
"new_name": "new_col_name"
}Removes a column from a table.
{
"action": "drop-column",
"table": "users",
"col_name": "col_to_remove"
}{
"action": "add-row",
"table": "users",
"data": {
"username": "jdoe",
"email": "jdoe@example.com"
}
}{
"action": "edit-row",
"table": "users",
"rowid": "1",
"data": {
"email": "new_email@example.com"
}
}{
"action": "delete-row",
"table": "users",
"rowid": "1"
}