CozoDB React Native plugin with Cypher-to-Datalog translation
npm install react-native-cozoA React Native plugin for CozoDB - an embedded relational-graph-vector database with Datalog.
Features:
- Full CozoDB functionality via native TurboModules (JSI)
- Cypher-to-Datalog query translation
- React hooks for queries and mutations
- Multiple storage backends (Memory, SQLite, RocksDB)
- TypeScript support
- React Native New Architecture (0.76+) support
- Expo support with config plugins (development builds)
``bash`
npm install react-native-cozoor
yarn add react-native-cozo
`bash`
cd ios && pod install
No additional setup required.
For Expo projects, see EXPO.md for detailed instructions. Quick start:
`bash`
npx expo install react-native-cozo
Add to app.json:`json`
{
"expo": {
"plugins": ["react-native-cozo"]
}
}
Then create a development build:
`bash`
npx expo prebuild
npx expo run:ios # or npx expo run:android
`tsx
import { CozoProvider, useQuery, useMutation } from 'react-native-cozo';
function App() {
return (
onReady={(db) => console.log('Database ready')}
>
);
}
`
`tsx
import { useQuery, useCypher } from 'react-native-cozo';
function PersonList() {
// Datalog query
const { data, loading, error, refetch } = useQuery(
?[name, age] := *Person[id, name, age], age > 21
);
// Or use Cypher syntax
const cypherResult = useCypher(
MATCH (p:Person) WHERE p.age > 21 RETURN p.name, p.age
);
if (loading) return
if (error) return
return (
renderItem={({ item }) =>
/>
);
}
`
`tsx
import { useMutation } from 'react-native-cozo';
function AddPerson() {
const { mutate, loading } = useMutation(
?[id, name, age] <- [[$id, $name, $age]]
:put Person { id, name, age }
);
const handleAdd = () => {
mutate({ id: '123', name: 'Alice', age: 30 });
};
return (
);
}
`
`tsx
import { useCozo, useCozoDatabase } from 'react-native-cozo';
function MyComponent() {
const { db, isReady, run, cypher } = useCozo();
// Or get the database instance directly
const database = useCozoDatabase();
const query = async () => {
// Run Datalog
const result = await run('?[x] <- [[1], [2], [3]]');
// Run Cypher (auto-translated)
const cypherResult = await cypher('MATCH (n:Person) RETURN n.name');
// Create a relation
await db.createRelation('users', { id: 'String', name: 'String' });
// Insert data
await db.insert('users', [
{ id: '1', name: 'Alice' },
{ id: '2', name: 'Bob' },
]);
};
}
`
The context provider for database access.
`tsx`
engine: 'sqlite', // 'mem' | 'sqlite' | 'rocksdb'
path: 'database.db',
options: {}
}}
onReady={(db) => {}}
onError={(error) => {}}
>
{children}
Hooks for executing queries with automatic state management.
`tsx`
const {
data, // Query result rows
headers, // Column headers
loading, // Loading state
error, // Error if any
took, // Query execution time
refetch, // Function to re-execute query
} = useQuery(query, params, options);
Options:
- skip - Skip query executionpollInterval
- - Auto-refresh interval in mscacheKey
- - Custom cache keyonSuccess
- / onError - Callbacks
Hooks for executing mutations.
`tsx`
const {
data, // Result data
loading, // Loading state
error, // Error if any
mutate, // Execute function
reset, // Reset state
} = useMutation(query, options);
The main database class.
`tsx
import { CozoDatabase, StorageEngine } from 'react-native-cozo';
const db = new CozoDatabase({
engine: StorageEngine.SQLite,
path: 'mydb.db',
});
await db.open();
// Run queries
const result = await db.run('?[x] <- [[1, 2, 3]]');
// Execute Cypher
const cypherResult = await db.cypher('MATCH (n) RETURN n');
// Translate Cypher to Datalog
const datalog = db.translateCypher('MATCH (n:Person) RETURN n.name');
// Schema operations
await db.createRelation('users', { id: 'String', name: 'String' }, ['id']);
const relations = await db.relations();
const schema = await db.schema('users');
await db.dropRelation('users');
// Data operations
await db.insert('users', { id: '1', name: 'Alice' });
await db.delete('users', { id: '1' });
// Import/Export
const data = await db.exportRelations(['users']);
await db.importRelations(data);
// Backup/Restore
await db.backup('/path/to/backup');
await db.restore('/path/to/backup');
// Transactions
await db.transaction([
'?[id, name] <- [["1", "Alice"]]',
':put users { id, name }',
]);
// Graph operations
const nodeId = await db.createNode('Person', { name: 'Alice' });
await db.createRelationship('KNOWS', nodeId1, nodeId2, { since: 2020 });
await db.close();
`
The library includes a Cypher-to-Datalog translator. For complete documentation, see CYPHER.md.
`typescript
import { translateCypher, useCozo } from 'react-native-cozo';
// Basic query
const datalog = translateCypher('MATCH (n:Person) RETURN n.name');
// Output: ?[name] := *Person{name}
// With conditions
translateCypher("MATCH (e:Employee) WHERE e.department = 'Engineering' RETURN e.name");
// Output: ?[name] := *Employee{department, name}, department == "Engineering"
// Aggregations
translateCypher('MATCH (e:Employee) RETURN e.department, count(*)');
// Output: ?[department, count(id)] := *Employee{department, id}
`
| Category | Features |
|----------|----------|
| Patterns | Nodes, relationships, labels, properties, variable-length paths |
| Clauses | MATCH, WHERE, RETURN, CREATE, DELETE, SET, MERGE |
| Operators | =, <>, <, >, AND, OR, NOT, IN, IS NULL |CONTAINS
| String | , STARTS WITH, ENDS WITH, toUpper, toLower |count
| Aggregations | , sum, avg, min, max, collect, stdev |ORDER BY
| Modifiers | , LIMIT, SKIP, DISTINCT |abs
| Math | , ceil, floor, round, sqrt, log, trig functions |
See CYPHER.md for the complete translation reference, examples, and limitations.
- StorageEngine.Memory - In-memory (default)StorageEngine.SQLite
- - SQLite-backed persistent storageStorageEngine.RocksDB
- - RocksDB-backed persistent storage
See CONTRIBUTING.md for development setup, testing instructions, and contribution guidelines.
All database operations may throw CozoError:
`tsx
import { CozoError, CozoErrorCode } from 'react-native-cozo';
try {
await db.run('invalid query');
} catch (error) {
if (error instanceof CozoError) {
console.log(error.code); // Error code
console.log(error.message); // Error message
console.log(error.display); // User-friendly message
}
}
``
MPL-2.0