A modern, local-first API development and collaboration platform built with Rust, Tauri, Svelte, and Go.
Slinger is a cross-platform API development platform designed for individual developers, teams, and organizations.
The platform provides:
The system is designed from day one to support both:
without requiring major architectural changes.
npm install
npm run dev
In another shell, if you want to build the Rust Tauri backend:
cd src-tauri
cargo build
To run the full desktop app:
npm run tauri:dev
Linux only: building the Tauri backend requires native packages such as
pkg-config,libgtk-4-dev,libglib2.0-dev, andlibwebkit2gtk-4.1-dev.
The local SQLite database file is created automatically at src-tauri/slinger.db.
The local database is the primary source of truth.
Users should never lose functionality because a remote server is unavailable.
All core functionality must work without internet access.
Synchronization is optional.
Every resource belongs to a workspace.
No exceptions.
A default workspace is automatically created:
Personal
Every entity is designed for future synchronization.
The MVP must not assume a single-user environment.
Organizations must be able to deploy:
Desktop App
+
Go Backend
+
PostgreSQL
inside their own infrastructure.
The architecture must support future:
without major rewrites.
Primary Target:
Secondary Targets:
Future:
Every entity uses UUIDv7.
Reason:
Rust:
uuid = { version = "1", features = ["v7", "serde"] }
Example:
let id = Uuid::now_v7();
Never store secrets directly in SQLite.
Store secrets using OS-native secure storage.
Linux:
Windows:
macOS:
Rust:
keyring = "3"
SQLite stores references only.
┌──────────────────────────────────────────────┐
│ Desktop Client │
├──────────────────────────────────────────────┤
│ Svelte │
│ TypeScript │
│ TailwindCSS │
│ shadcn/ui │
├──────────────────────────────────────────────┤
│ Tauri │
├──────────────────────────────────────────────┤
│ Application Layer │
├──────────────────────────────────────────────┤
│ Services │
├──────────────────────────────────────────────┤
│ Domain Models │
├──────────────────────────────────────────────┤
│ Repositories │
├──────────────────────────────────────────────┤
│ SQLite │
└───────────────────┬──────────────────────────┘
│
│ Future
▼
┌──────────────────────────────────────────────┐
│ Go Backend │
├──────────────────────────────────────────────┤
│ Authentication │
│ Users │
│ Workspaces │
│ Collections │
│ Environments │
│ Permissions │
│ Sync Engine │
│ Audit Logs │
└───────────────────┬──────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ PostgreSQL │
└──────────────────────────────────────────────┘
UI
↓
Tauri Commands
↓
Application Services
↓
Domain Models
↓
Repositories
↓
Database
The UI must never directly manipulate persistence.
Business logic belongs in services.
Features:
No backend.
Features:
Still offline.
Features:
Features:
Features:
Every resource belongs to a workspace.
Workspace
│
├── Collections
├── Environments
├── History
├── Members
├── Audit Logs
└── Settings
Personal
Team
Database:
workspace_type TEXT NOT NULL
Personal workspace is automatically created during first launch.
Can:
Can:
Can:
Can:
Support:
Support:
Support:
Future:
{{base_url}}
{{token}}
{{username}}
Resolved before execution.
Store:
The architecture must remain protocol extensible.
Not part of MVP.
Potential plugins:
GraphQL
gRPC
Kafka
MQTT
SOAP
WebSocket
Plugins must integrate with the domain layer.
Request definitions are stored as structured JSON documents.
Example:
{
"id": "uuid",
"name": "Get Users",
"method": "GET",
"url": "https://api.example.com/users",
"headers": [],
"params": [],
"auth": {},
"body": {}
}
Benefits:
Every synchronized entity contains:
id TEXT PRIMARY KEY,
version INTEGER DEFAULT 1,
deleted BOOLEAN DEFAULT FALSE,
created_at DATETIME,
updated_at DATETIME
All IDs are UUIDv7.
CREATE TABLE workspaces (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
workspace_type TEXT NOT NULL,
version INTEGER DEFAULT 1,
deleted BOOLEAN DEFAULT FALSE,
created_at DATETIME,
updated_at DATETIME
);
CREATE TABLE collections (
id TEXT PRIMARY KEY,
workspace_id TEXT NOT NULL,
name TEXT NOT NULL,
version INTEGER DEFAULT 1,
deleted BOOLEAN DEFAULT FALSE,
created_at DATETIME,
updated_at DATETIME
);
CREATE TABLE folders (
id TEXT PRIMARY KEY,
collection_id TEXT NOT NULL,
parent_folder_id TEXT,
name TEXT NOT NULL,
version INTEGER DEFAULT 1,
deleted BOOLEAN DEFAULT FALSE,
created_at DATETIME,
updated_at DATETIME
);
CREATE TABLE requests (
id TEXT PRIMARY KEY,
workspace_id TEXT NOT NULL,
collection_id TEXT,
folder_id TEXT,
name TEXT NOT NULL,
document_json TEXT NOT NULL,
version INTEGER DEFAULT 1,
deleted BOOLEAN DEFAULT FALSE,
created_at DATETIME,
updated_at DATETIME
);
CREATE TABLE environments (
id TEXT PRIMARY KEY,
workspace_id TEXT NOT NULL,
name TEXT NOT NULL,
version INTEGER DEFAULT 1,
deleted BOOLEAN DEFAULT FALSE,
created_at DATETIME,
updated_at DATETIME
);
CREATE TABLE environment_variables (
id TEXT PRIMARY KEY,
environment_id TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL
);
CREATE TABLE history (
id TEXT PRIMARY KEY,
workspace_id TEXT NOT NULL,
request_id TEXT,
method TEXT,
url TEXT,
status_code INTEGER,
duration_ms INTEGER,
created_at DATETIME
);
CREATE TABLE sync_queue (
id TEXT PRIMARY KEY,
entity_type TEXT NOT NULL,
entity_id TEXT NOT NULL,
operation TEXT NOT NULL,
created_at DATETIME
);
Local database remains source of truth.
Workflow:
Local Change
↓
Sync Queue
↓
Push To Server
↓
Receive Remote Changes
↓
Merge
Future API contract:
{
"entityType": "collection",
"entityId": "uuid",
"version": 4,
"operation": "update",
"payload": {}
}
This contract should remain stable.
Future support:
Future support:
workspace/
├── collections/
├── environments/
└── slinger.json
This allows:
Directory:
src-tauri/migrations/
Example:
0001_create_workspaces.sql
0002_create_collections.sql
0003_create_requests.sql
Never generate schema in code.
Always use migration files.
src/
app/
components/
hooks/
lib/
services/
features/
├── workspaces/
├── collections/
├── requests/
├── environments/
├── history/
├── settings/
└── sync/
Feature-first architecture is mandatory.
src-tauri/src/
commands/
├── workspaces.rs
├── collections.rs
├── requests.rs
├── environments.rs
├── history.rs
└── sync.rs
services/
├── workspace_service.rs
├── collection_service.rs
├── request_service.rs
├── environment_service.rs
repositories/
├── workspace_repository.rs
├── collection_repository.rs
├── request_repository.rs
├── environment_repository.rs
models/
├── workspace.rs
├── collection.rs
├── request.rs
├── environment.rs
http/
├── client.rs
└── executor.rs
sync/
├── queue.rs
├── versioning.rs
└── protocol.rs
utils/
├── ids.rs
├── secrets.rs
└── resolver.rs
┌────────────────────────────────────────────────────┐
│ Top Navigation │
├────────────────────────────────────────────────────┤
│ Workspace Selector │
├───────────────┬────────────────────────────────────┤
│ Collections │ Request Tabs │
│ Tree ├────────────────────────────────────┤
│ │ URL + Method + Send │
│ ├────────────────────────────────────┤
│ │ Params │
│ │ Headers │
│ │ Auth │
│ │ Body │
│ ├────────────────────────────────────┤
│ │ Response │
│ └────────────────────────────────────┘
└───────────────┴────────────────────────────────────┘
Startup:
< 2 seconds
Memory:
< 300 MB
Request Execution:
Non-blocking
A user can:
without requiring:
while remaining fully compatible with future: