@apsolut/n8n-nodes-turso
v0.9.1
Published
n8n community node for Turso / libSQL databases — zero runtime dependencies (HTTP pipeline API)
Maintainers
Readme
n8n-nodes-turso
n8n community node for Turso / libSQL databases — zero runtime dependencies. Talks to the database over the Hrana HTTP pipeline API, so there is no native driver to build and nothing extra to install.
Why
n8n ships Postgres (raw SQL) and Supabase (PostgREST row CRUD). Turso is SQLite-compatible edge SQL with a generous free tier — great as a workflow state store, dedup ledger, or lightweight analytics DB — but has no built-in node.
| n8n node | Protocol | Best for | |----------|----------|----------| | Postgres | PostgreSQL wire | Full SQL, self-hosted PG | | Supabase | PostgREST HTTP | Table CRUD without SQL | | Turso (this) | libSQL HTTP pipeline | Edge SQLite: state, dedup ledgers, prototypes |
Installation
Self-hosted n8n: Settings → Community Nodes → Install → @apsolut/n8n-nodes-turso.
Credentials
Create a Turso API credential:
- Database URL —
libsql://your-db-org.turso.io(orhttps://…) - Auth Token —
turso db tokens create <db>
The credential test runs SELECT 1 against your database.
Operations
Execute Query
Arbitrary SQL with ? placeholders. Query Parameters accepts a JSON array ([40, "text with, commas"] — safe for values containing commas) or a plain comma-separated list (40, open).
Execute Batch
Run several statements in a single pipeline round trip. Each statement has its own SQL and parameters; results are returned per statement. Enable Run as Transaction to make the batch atomic: statements execute inside one transaction (via conditional Hrana batch steps) and every change rolls back if any statement fails.
Insert
Insert one row per input item. Auto-map the input JSON (with an ignore list) or define columns explicitly. Values bind as typed ? parameters — no SQL injection surface.
Select
Table read with optional WHERE (parameterized), ORDER BY, and limit.
Update
Set columns on rows matching a parameterized WHERE clause. Values and WHERE parameters bind as typed ? placeholders. Runs once per input item, so values can be expression-driven.
Delete
Remove rows matching a parameterized WHERE clause. Leaving WHERE empty deletes all rows in the table — use with care.
List Tables
List user tables (sqlite_master), or describe one table's columns (PRAGMA table_info) when a table name is given.
Behavior notes
- Identifiers are quoted. Table and column names (including auto-mapped input keys) are bound as quoted SQLite identifiers, so they cannot alter the SQL. Names are used verbatim —
main.usersis treated as one identifier containing a dot, not a schema qualifier. - Big integers stay exact. Integer values beyond
Number.MAX_SAFE_INTEGER(2⁵³ − 1) — int64 ids, snowflake ids — are returned as strings instead of silently losing precision. - Query metrics. Set Output Only Result Data to false (under Options) to include
rowsAffected,lastInsertRowid, and per-statement server metrics:rowsRead,rowsWritten,queryDurationMs. Turso bills by rows read/written, so this doubles as cost observability.
Patterns that work well
- Idempotent ledgers:
INSERT OR IGNORE INTO seen (key) VALUES (?)— safe under retries. - Upserts:
INSERT OR REPLACE …via Execute Query. - Read once per run: enable Execute Once on lookup queries, or they run once per input item (standard n8n behavior).
- Turso node output replaces the incoming item — read earlier fields via
$('Node Name').first().json.x.
Compatibility
- n8n ≥ 1.x (built with
@n8n/node-cli; tested on n8n 2.x) - Turso Cloud and any libSQL server exposing the Hrana HTTP endpoint (
/v2/pipeline) - Not supported: local
file:SQLite and:memory:databases (those require the native@libsql/client; this node is deliberately HTTP-only to stay dependency-free)
Try it
- Import examples/turso-smoke.workflow.json into n8n and attach your credential.
- Or test the transport without n8n:
npm run build && TURSO_DATABASE_URL=... TURSO_AUTH_TOKEN=... node test/protocol-smoke.mjs
