LogoKnex Dart
knex-dartkartikey321/knex-dart 999999

Migrating from Knex.js

Transition your Knex.js knowledge to Knex Dart

Migrating from Knex.js#

Knex Dart provides near-100% API parity with Knex.js. If you know Knex.js, you already know most of Knex Dart!

Key Differences#

1. Explicit Operators#

Knex.js (implicit =):

knex('users').where('name', 'John')

Knex Dart (explicit operator):

knex('users').where('name', '=', 'John')

2. Reserved Keywords#

Knex.js:

knex.with('cte', query).select('*').from('cte')

Knex Dart (with is a Dart keyword):

knex.withQuery('cte', query).select(['*']).from('cte')

3. Array Syntax#

Knex.js:

knex('users').select('id', 'name')
// or
knex('users').select(['id', 'name'])

Knex Dart (always use lists):

knex('users').select(['id', 'name'])

4. Client Configuration#

Knex.js:

const knex = require('knex')({
  client: 'pg',
  connection: {
    host: 'localhost',
    database: 'myapp'
  }
});

Knex Dart:

// Query building only (current)
final knex = Knex(client: MockClient());

// PostgreSQL (coming soon)
final knex = await Knex.postgres(
  host: 'localhost',
  database: 'myapp',
);

5. Async/Await#

Knex.js:

const users = await knex('users').select('*');

Knex Dart (same!):

final users = await knex('users').select(['*']);

Feature Parity Matrix#

FeatureKnex.jsKnex DartNotes
SELECT100%
INSERT100%
UPDATE100%
DELETE100%
WHERE (basic)Explicit operators
WHERE IN100%
WHERE NULL100%
WHERE BETWEEN100%
WHERE COLUMN100%
WHERE NOT100%
WHERE EXISTS100%
WHERE WRAPPED100%
JOINs (all types)100%
Callback JOINs100%
GROUP BY100%
HAVING100%
ORDER BY100%
LIMIT/OFFSET100%
Aggregates100%
Subqueries (WHERE)100%
Subqueries (FROM)100%
Subqueries (SELECT)100%
UNION100%
UNION ALL100%
CTEswithQuery()
Recursive CTEswithRecursive()
Raw queries100%
RETURNING100%
Window Functions🔶Coming soon
CASE statements🔶Planned
Transactions🔶Coming soon
PostgreSQL🔶In progress
MySQL🔶Planned
SQLite🔶Planned

Current Coverage: ~90% query building API

Migration Examples#

Simple Query#

Knex.js:

knex('users')
  .select('id', 'name')
  .where('active', true)
  .orderBy('name');

Knex Dart:

knex('users')
  .select(['id', 'name'])
  .where('active', '=', true)
  .orderBy('name');

JOIN with WHERE#

Knex.js:

knex('users')
  .join('orders', 'users.id', 'orders.user_id')
  .where('orders.status', 'completed')
  .select('users.name', 'orders.total');

Knex Dart:

knex('users')
  .join('orders', 'users.id', 'orders.user_id')
  .where('orders.status', '=', 'completed')
  .select(['users.name', 'orders.total']);

Subquery#

Knex.js:

knex('users').whereIn('id',
  knex('orders').select('user_id').where('total', '>', 1000)
);

Knex Dart (identical!):

knex('users').whereIn('id',
  knex('orders').select(['user_id']).where('total', '>', 1000)
);

CTE#

Knex.js:

knex.with('high_value', knex('orders').where('amount', '>', 1000))
  .select('*').from('high_value');

Knex Dart:

knex.withQuery('high_value', knex('orders').where('amount', '>', 1000))
  .select(['*']).from('high_value');

Quick Reference#

Common Patterns#

OperationKnex.jsKnex Dart
Select all.select('*').select(['*'])
Multiple where .where('a', 1).where('b', 2) .where('a', '=', 1).where('b', '=', 2)
Where in list .whereIn('id', [1,2,3]) .whereIn('id', [1,2,3])
Join .join('t', 'a.id', 'b.id') .join('t', 'a.id', 'b.id')
CTE.with('cte', ...).withQuery('cte', ...)

Method Name Changes#

Knex.jsKnex DartReason
.with() .withQuery() with is Dart keyword

That's it! Only one method name is different.

Tips for Migration#

  1. Add Explicit Operators - Always specify =, >, etc.
  2. Use Lists for Arrays - select(['a', 'b']) not select('a', 'b')
  3. withQuery not with - Remember the rename
  4. Test Incrementally - Port queries one at a time

What's Missing?#

Currently not implemented (coming soon):

  • Window functions
  • CASE statements
  • INTERSECT/EXCEPT
  • Actual database connections (PostgreSQL in progress)
  • Transactions
  • Schema builder
  • Migrations

Getting Help#

Community#

Join the Dart/Flutter community: