| theme | ./theme | ||||
|---|---|---|---|---|---|
| title | WarpDrive: Set Data to Stun | ||||
| info | Discover WarpDrive, the next-generation data framework that brings universal compatibility and performance to ambitious web applications. This talk explores WarpDrive's schema-driven architecture through building a real application, demonstrating how to boldly go where your data has never gone before with a truly framework-agnostic layer. Learn how WarpDrive's TypeScript-first approach delivers enterprise-grade features while eliminating traditional data management complexity. | ||||
| author | Krystan HuffMenne | ||||
| keywords | WarpDrive,EmberData,JavaScript,TypeScript,Framework,Data Layer,EmberFest | ||||
| lineNumbers | true | ||||
| drawings |
|
||||
| transition | slide-left | ||||
| mdc | true | ||||
| favicon | ./favicon.png | ||||
| selectable | true |
Krystan HuffMenne • Staff Engineer @ AuditBoard
After Party talking points:
Portland, Oregon
Answers to “mom”
Staff Engineer @ AuditBoard
EmberData/WarpDrive & Tooling Teams
Ember veteran since v2
::right::
Where are we boldly going next?
...the lightweight data framework for ambitious web applications.
Unlike other data libraries, WarpDrive is built around:
- Resource-first architecture instead of heavy model inheritance patterns
- Schema-driven development for consistent, sharable data shapes
- Universal compatibility vs. framework-specific implementations
- Fine-grained reactivity that JustWorks™
Implemented in multiple frameworks to compare approaches.
As a user I can...
...create a Todo.
...read lists of:
All Todos, Active Todos, and Completed Todos.
...update each Todo.
...delete a Todo.
...perform bulk actions:
toggle and delete.
a string id
a string title attribute
a boolean completed attribute
We'll re-implement the Ember TodoMVC application using:
- WarpDrive (our starship for data management)
- {JSON:API} (the gold standard for API communication)
- TypeScript (because we like our data typed and our code safe)
- Modern Ember Polaris (the latest and greatest Ember patterns)
Live Demo: TodoMVC Feature Set
It's in command.
<<< @/packages/shared-data/src/stores/index.ts ts {20|20|21|28-37|39-44|46-52}{maxHeight: '200px'}- Manages Requests — How we handle requests for data
- Manages the Cache — How to cache that data
- Manages Schemas — Schemas for what our data looks like
- Manages Reactive State — What sort of reactive objects to create for that data
import { useRecommendedStore } from '@warp-drive/core';
import { JSONAPICache } from '@warp-drive/json-api';
import { ApiHandler, useApiHandler } from '../handlers/api.ts';
import { FlagSchema } from '../schemas/flag.ts';
import { TodoSchema } from '../schemas/todo.ts';
export default useRecommendedStore({
// RequestManager config
handlers: [
// Use `APIHandler` if `useApiHandler` returns true
new Gate(ApiHandler, useApiHandler),
// APIHandler calls `next()` to pass the request to `fetch`
// Fetch handler is included last by default
],
cache: JSONAPICache, // Cache config
schemas: [FlagSchema, TodoSchema], // SchemaService config
});It manages all external contact.
<<< @/packages/shared-data/src/stores/index.ts ts {21|21|26|22-27|28|21-28}{maxHeight: '200px'}- Fetch Handler — Makes actual network requests (Fetch API + error handling)
- Request Pipeline — Allows custom handlers for data transformation
- Cache Integration — Automatically caches responses
By default, WarpDrive speaks {JSON:API} fluently, giving you:
{
"data": [
{
"type": "todo",
"id": "1",
"attributes": {
"title": "Learn WarpDrive",
"completed": false
}
}
// ...
]
}Standardized format for:
resources,
relationships,
errors
Built-in conventions for:
pagination,
filtering,
sorting,
sparse fields
WarpDrive supports:
all
of
the
above
import Route from '@my-framework/routing/route';
import { service } from '@my-framework/service';
import type { Store } from '@workspace/shared-data';
export default class ActiveTodos extends Route {
@service declare store: Store;
model() {
return this.store.request({
method: 'GET',
url: '/api/todo',
// Additional options like headers, query params, etc.
})
}
}interface RequestInfo extends RequestInit {
// Standard Fetch API options
method: 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'PUT'; // etc
url: string;
// Caching options
op?: string;
cacheOptions?: {
types?: string[];
key?: string;
reload?: boolean;
backgroundReload?: boolean;
};
// Custom handler options
options?: Record<string, unknown>;
// ...
}Our getAllTodos builder
Specifies the request method
Generates the URL
Sets cache options:'query' op, 'todo' type
Our createTodo builder
Sets cache options:'createRecord' op, 'todo' type
- Our
getCompletedTodosbuilder buildQueryParamsutil
Instead of models with complex inheritance, WarpDrive uses simple, declarative schemas:
withDefaultssets up defaults, like theidfieldtypedefines the resource typefieldsdefines the shape of the resource- Check out Mehul's talk about "ReactiveResources & Schema‑Driven Data Handling"
- Types for various states:
TodoAttributestype- Readonly
Todotype EditableTodotype
Yes, and they're perfectly structured!
"Roger that, Captain. Sending request to the API."
"{JSON:API}$%^$@&$%#&!@*&^%$%%$##@$%^$@&$%#&!@*&!@*! !@*&^%$#@!#&^%%$$@@!!@#$%^&*&%%$##@$%^$%^{/JSON:API}"
- Provides Ember components — For request UX with elegant control flow.
- A Thin Wrapper — Built on top of
@warp-drive/corereactive utilities. - Reactive — Leverages Ember's reactivity system for fine-grained updates that JustWork™.
<Request />component- Loading state
- Error state
- Success state
- Autorefresh
- ...and more!
Live Demo: Basic Request Loading States
Live Demo: Basic Error States
<<< @/apps/emberjs/app/components/todo-app/todo-provider-request-version.gts ts {14-27|14-27}{maxHeight: '460px'}
The core logic stays the same — only the framework integration changes!
import { Request } from '@warp-drive/react';
import { getAllTodos } from '@workspace/shared-data/builders';
import type { Todo } from '@workspace/shared-data/types';
export function TodoProvider() {
return (
<Request
query={getAllTodos()}
states={{
loading: ({ state }) => <div>React Loading Spinner!</div>,
content: ({ result }) => <div>React Todo List</div>,
error: ({ state }) => (
<div>
<h2 class="error-message">Please contact TodoMVC support.</h2>
<p>
<button onClick={state.retry}>Or DDOS us!</button>
</p>
</div>
),
}}
/>
);
}-
@warp-drive/ember -
@warp-drive/react -
@warp-drive/tc39-proposal-signals -
@warp-drive/vueSoon! -
@warp-drive/svelteSoon!
When changing data, you have two choices:
<<< @/apps/emberjs/app/components/todo-app/todo-item.gts gts {308-314|308-314|310}{maxHeight: '200px'}
- Our
patchTodoTitleaction - Uses our
patchTodobuilder - Pass the
Todoandattributesto update - When the request resolves, that
Todoupdates all over your app - This seems too easy...
- Our
patchTodobuilder - Specifies the request method
- Generates the URL
- Serializes the request body
- Sets cache options
- tl;dr: It will update our Todos
Live Demo: Pessimistic Mutation
<<< @/apps/emberjs/app/components/todo-app/todo-item.gts gts {308-314|308-314|310}{maxHeight: '200px'}
<<< @/packages/shared-data/src/builders/todo/update.ts gts {17-37|17-37|21-36}{maxHeight: '460px'}
- Uses the same
patchTodobuilder, but this time with a mutatedEditableTodo
- By default, resources are immutable
- To get a mutable version, we use
await checkout(todo) - Pass the mutable
EditableTodoto our<TodoItem />component <Await />component handles promise states declaratively
- Our
patchTodoToggleaction - Patch the cached filter query documents manually
cache.patch()surgically updates cached documents- Add to completed list; remove from active list
Live Demo: Optimistic Mutation and Cache Patching
<<< @/apps/emberjs/app/components/todo-app/todo-item.gts gts {186-203|186-203|191-198}{maxHeight: '460px'}
<<< @/packages/shared-data/src/builders/todo/update.ts gts {17-37|17-37|21-36}{maxHeight: '460px'}
<<< @/packages/shared-data/src/builders/todo/update.ts gts {58-90|58-90|63-85}{maxHeight: '460px'}
Whether you choose"pessimistic" or "locally optimistic" updates:
- Original data stays immutable
- Changes are isolated until saved
...without temporal paradoxes!"
WarpDrive optimizes automatically:
- Request deduplication — Same request? Use cached result
- Fine-grained reactivity — Only update what actually changed
Live Demo: Scale Pioneers
Live Demo: Enterprise Edition
<Paginate /> component
(coming soon for real)
Loading and error states
Success state
(display all loaded data or just current page)
Pagination controls
Autorefresh
<<< @/apps/emberjs/app/components/todo-app/pagination-controls.gts ts {30-42|30-42|33-37|52-58}{maxHeight: '200px',lines:false}
- Previous and next page buttons + page links
<EachLink />component- Yields a
<:link>block for each known page link - Yields a
<:placeholder>block for unknown links
- Our
getAllTodosbuilder - Pagination query params
{
"data": [
/* the first page of Todos */
],
"links": {
"self": "/api/todo?page[limit]=5&page[offset]=0",
"first": "/api/todo?page[limit]=5&page[offset]=0",
"next": "/api/todo?page[limit]=5&page[offset]=5",
"last": "/api/todo?page[limit]=5&page[offset]=99995"
},
"meta": {
"currentPage": 1,
"totalPages": 20000
}
}- Our paginated
/api/todoresponse - Returns a
linksobject - Returns a
meta— required only forEachLinksupport
<<< @/apps/emberjs/app/components/todo-app/todo-provider.gts ts {30|30|91-103}{maxHeight: '360px'}
<Paginate />component@pageHintsargument- Extracts pagination meta for use in
EachLink
<<< @/apps/emberjs/app/components/todo-app/todo-provider.gts ts {28-51|28-51|30,32,34,36,39,41,43,45,47|91-103}{maxHeight: '460px',lines:false}
<<< @/apps/emberjs/app/components/todo-app/pagination-controls.gts ts {30-42|30-42|33,35,37|50-60|52-58}{maxHeight: '380px'}
<<< @/packages/shared-data/src/builders/todo/query.ts ts {9-24|9-24|11-23}{maxHeight: '380px'}
Load the entire Todo list just to perform bulk operations...
- Our
bulkDeleteCompletedTodosbuilder - Specifies the request method
- Generates the URL
- No body, no cache options
- Query params filter
- Expects empty response
- Our
invalidateAllTodoQueriesutil invalidateRequestsForTypemethod
Live Demo: Bulk Actions
- Our
clearCompletedaction - Our
bulkDeleteCompletedTodosbuilder - Our
invalidateAllTodoQueriesutility
<<< @/packages/shared-data/src/builders/todo/bulk.ts ts {154-167|158-166}{maxHeight: '360px'}
<<< @/packages/shared-data/src/builders/todo/query.ts ts {71-74|73}{maxHeight: '360px'}
WarpDrive is the lightweight data framework for ambitious web applications.
- Try WarpDrive in your next project, regardless of framework.
- Explore the guides at docs.warp-drive.io and canary.warp-drive.io.
- Explore this WarpDrive TodoMVC monorepo at github.com/gitKrystan/2025-emberfest.
- Join the community discussions on Discord: https://discord.gg/eUPwQzRJ.
- Build something ambitious!
AuditBoard, Chris Thoburn, Julia Donaldson, Natasha Wolfe
My mom, who's seen this talk four times
(and my husband for being super-dad the last month while I prepared it)
The human adventure is just beginning...
And so is your journey with WarpDrive
The data is out there — go boldly and fetch it efficiently




