Wings is a modern TypeScript library providing universal database adapters with a unified interface. It enables seamless integration of different databases into any TypeScript or JavaScript application with advanced features like smart pagination, type safety, and comprehensive query operators.
- Overview
- Wings vs FeathersJS Adapters
- Key Features
- Installation
- Quick Start
- Available Adapters
- FeathersJS Compatibility
- Development
- Testing
- Contributing
- License
Wings provides a consistent, type-safe interface for working with different databases. Whether you're using MongoDB, PostgreSQL, MySQL, SQLite, or even in-memory storage, Wings offers the same intuitive API with database-specific optimizations.
- Universal Interface: One API to rule them all - works consistently across all databases
- Type Safety: Full TypeScript support with automatic type inference
- Performance First: Smart pagination, optimized queries, and minimal overhead
- Database Native: Leverages each database's unique features while maintaining consistency
- Modern Patterns: Built for contemporary TypeScript applications
Wings represents the next evolution of database adapters, building on lessons learned from FeathersJS while introducing modern patterns and improved developer experience.
Feature | Wings Adapters | FeathersJS Adapters |
---|---|---|
Return Types | Smart returns - arrays by default, Paginated<T> when explicitly requested |
Always returns Paginated<T> objects |
Error Handling | Returns null for not-found cases |
Throws NotFound errors |
Bulk Operations | Explicit patchMany() and removeMany() methods with safety controls |
Uses patch(null) and remove(null) patterns |
Type Inference | Automatic TypeScript inference based on parameters | Manual type assertions often needed |
Query Operators | Extended operators including $like , $ilike , $isNull |
Standard operators only |
Update Method | Single patch() method for all updates |
Separate update() and patch() methods |
Safety | Built-in safety controls for bulk operations | No built-in safety mechanisms |
// Wings Adapter - Modern, intuitive patterns
const users = await adapter.find({ query: { active: true } }) // Returns User[]
const paginated = await adapter.find({ query: { active: true }, paginate: true }) // Returns Paginated<User>
const user = await adapter.get(123) // Returns User | null
// Bulk operations with safety
await adapter.patchMany({ active: false }, { query: { role: 'admin' } }) // Fails - needs allowAll
await adapter.patchMany({ active: false }, { query: { role: 'admin' }, allowAll: true }) // Success
// FeathersJS Adapter - Legacy patterns
const result = await adapter.find({ query: { active: true } }) // Always Paginated<User>
const users = result.data // Extra step to get array
const user = await adapter.get(123) // Throws NotFound if missing
// Bulk operations without safety
await adapter.patch(null, { active: false }, { query: { role: 'admin' } }) // No safety check
Automatically returns the right type based on your needs - simple arrays for basic queries, paginated results when you need counts.
Full TypeScript support with generics, type inference, and compile-time safety.
No more try-catch blocks for not-found errors - operations return null
when items don't exist.
Built-in protection against accidental mass updates or deletions with explicit allowAll
requirements.
Beyond basic queries with SQL-like operators: $like
, $ilike
, $isNull
, and more.
Write once, run anywhere - your code works the same whether using MongoDB, PostgreSQL, or any other supported database.
Install the core package and your preferred adapter:
# Core interfaces (required)
npm install @wingshq/adapter-commons
# Choose your adapter
npm install @wingshq/memory # In-memory adapter
npm install @wingshq/mongodb # MongoDB adapter
npm install @wingshq/knex # SQL adapter (PostgreSQL, MySQL, SQLite)
npm install @wingshq/kysely # Type-safe SQL query builder
npm install @wingshq/db0 # Modern SQL with edge runtime support
import { MemoryAdapter } from '@wingshq/memory'
interface User {
id?: number
name: string
email: string
active: boolean
}
// Create an adapter instance
const users = new MemoryAdapter<User>({
id: 'id',
startId: 1
})
// Create users
const alice = await users.create({
name: 'Alice',
email: '[email protected]',
active: true
})
// Find active users (returns array)
const activeUsers = await users.find({
query: { active: true }
})
// Find with pagination (returns { data, total, limit, skip })
const paginatedUsers = await users.find({
query: { active: true },
paginate: true,
limit: 10
})
// Update a user (returns null if not found)
const updated = await users.patch(alice.id, {
active: false
})
// Bulk update with safety
await users.patchMany(
{ active: false },
{
query: { email: { $like: '%spam.com' } },
allowAll: true
}
)
Package | Description | Documentation |
---|---|---|
@wingshq/adapter-commons | Core interfaces and utilities | README |
@wingshq/adapter-tests | Shared test suite for adapters | README |
Package | Database Support | Documentation |
---|---|---|
@wingshq/memory | In-memory storage | README |
@wingshq/mongodb | MongoDB | README |
@wingshq/knex | PostgreSQL, MySQL, SQLite, and more | README |
@wingshq/kysely | Type-safe SQL query builder | README |
@wingshq/db0 | Modern SQL with edge runtime support | README |
Wings provides full backwards compatibility with FeathersJS through optional wrapper packages. This allows gradual migration and continued use of existing FeathersJS tooling.
Note: In Feathers v6, services and adapters are decoupled. Services handle API endpoints while adapters handle database operations. Wings adapters can be used directly or through FeathersJS compatibility wrappers.
// Import the FeathersJS wrapper
import { FeathersKnexAdapter } from '@wingshq/knex/feathers'
// Create adapter instance
const adapter = new FeathersKnexAdapter({
name: 'users',
Model: db
})
// All FeathersJS adapter patterns work unchanged
const paginated = await adapter.find({ query: { active: true } }) // Always returns Paginated<T>
const user = await adapter.get(123) // Throws NotFound if missing
await adapter.update(123, fullUserData) // Full update method available
- Drop-in Replacement: Start by replacing FeathersJS adapters with Wings compatibility wrappers
- Gradual Adoption: Migrate adapters to native Wings interface as needed
- Full Migration: Eventually move all adapters to Wings for best performance and developer experience
- Node.js >= 18
- npm >= 9
# Clone the repository
git clone https://github.com/feathersdev/wings.git
cd wings
# Install dependencies
npm install
# Build all packages
npm run compile
# Run tests
npm test
Each package in the monorepo has its own development commands:
# Navigate to a package
cd packages/mongodb
# Build the package
npm run compile
# Run tests
npm test
# Run tests with coverage
npm run coverage
# Lint code
npm run lint
# Fix linting issues
npm run lint:fix
For SQL adapters (knex, kysely, db0), you can test against different databases:
# Start PostgreSQL for testing
docker-compose up -d postgres
# Run tests with PostgreSQL
TEST_DB=postgres npm test
# Stop PostgreSQL
docker-compose down
Wings uses a comprehensive shared test suite to ensure consistency across all adapters.
# Run all tests
npm test
# Run tests for a specific package
npm run test -- packages/mongodb
# Run tests with coverage
npm run coverage
# Run tests in watch mode (using vitest)
cd packages/mongodb && npm run test:watch
Tests are organized into three categories:
- Common Tests: Shared functionality across all interfaces
- Wings Tests: Wings-specific features and behaviors
- FeathersJS Tests: Compatibility tests for FeathersJS wrappers
import { fullWingsTests } from '@wingshq/adapter-tests'
import { MyAdapter } from '../src'
// Run the full Wings test suite
fullWingsTests(
() => new MyAdapter({ id: 'id' }), // Service factory
'id', // ID property
{
// Test configuration
hasNullTypeSupport: true,
hasBooleanTypeSupport: true
}
)
We welcome contributions! Please see our Contributing Guide for details.
To generate a new adapter:
npm run generate:adapter
This will scaffold a new adapter package with:
- TypeScript configuration
- Test setup with the shared test suite
- Basic adapter implementation extending AdapterBase
- Package.json with standard scripts
- README template
All Wings adapters extend the AdapterBase
class from @wingshq/adapter-commons
, which provides:
- Common validation methods (
validateNonNullId
,validateBulkParams
) - Standard query filtering and separation logic
- Paginated result building
- SQL-like operator conversion for non-SQL databases
- Consistent error handling patterns
- Fork the repository
- Create a feature branch
- Make your changes
- Ensure all tests pass
- Submit a pull request
- We use ESLint and Prettier for code formatting
- Run
npm run lint
to check code style - Run
npm run lint:fix
to automatically fix issues
Copyright (c) 2012-Present Feathers.dev
Licensed under the MIT license.