
Security News
CVE Volume Surges Past 48,000 in 2025 as WordPress Plugin Ecosystem Drives Growth
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.
@ember-data/codemods
Advanced tools
WarpDrive is the lightweight data library for web apps —
universal, typed, reactive, and ready to scale.
Codemods for WarpDrive/EmberData paradigms.
npx @ember-data/codemods apply --help
The available codemods will be listed under the "Commands" heading.
npx @ember-data/codemods apply <codemod-name> [codemod-options] <target-glob-pattern...>
For example:
npx @ember-data/codemods apply legacy-compat-builders ./app/**/*.{js,ts}
To list the available options for a particular codemod, you can run:
npx @ember-data/codemods apply <codemod-name> --help
A set of codemods to help migrate EmberData models and mixins to WarpDrive schemas.
npx @ember-data/codemods apply migrate-to-schema --help
Usage: @ember-data/codemods apply migrate-to-schema [options] [input-dir]
Migrates both EmberData models and mixins to WarpDrive schemas in batch.
Arguments:
input-dir Input directory to search for models and mixins (default: "./app")
Options:
-d, --dry dry run (no changes are made to files) (default: false)
-v, --verbose <level> Show more information about the transform process (choices: "0", "1",
"2", default: "0")
-l, --log-file [path] Write logs to a file. If option is set but no path is provided, logs are
written to ember-data-codemods.log
-i, --ignore <ignore-glob-pattern...> Ignores the given file or glob pattern. If using glob pattern, wrap in
single quotes.
--config <path> Path to configuration file
--models-only Only process model files (default: false)
--mixins-only Only process mixin files (default: false)
--skip-processed Skip files that have already been processed (default: false)
--model-source-dir <path> Directory containing model files (default: "./app/models")
--mixin-source-dir <path> Directory containing mixin files (default: "./app/mixins")
--output-dir <path> Output directory for generated schemas (default: "./app/schemas")
-h, --help display help for command
npx @ember-data/codemods apply model-to-schema --help
Usage: @ember-data/codemods apply model-to-schema [options] <target-glob-pattern...>
Transforms EmberData models to schema definitions for WarpDrive.
Arguments:
target-glob-pattern Path to files or glob pattern. If using glob pattern, wrap in single
quotes.
Options:
-d, --dry dry run (no changes are made to files) (default: false)
-v, --verbose <level> Show more information about the transform process (choices: "0", "1",
"2", default: "0")
-l, --log-file [path] Write logs to a file. If option is set but no path is provided, logs are
written to ember-data-codemods.log
-i, --ignore <ignore-glob-pattern...> Ignores the given file or glob pattern. If using glob pattern, wrap in
single quotes.
--input-dir <path> Input directory containing models (default: "./app/models")
--output-dir <path> Output directory for schemas (default: "./app/schemas")
--config <path> Path to configuration file
-h, --help display help for command
npx @ember-data/codemods apply mixin-to-schema --help
Usage: @ember-data/codemods apply mixin-to-schema [options] <target-glob-pattern...>
Transforms EmberData mixins to schema traits for WarpDrive.
Arguments:
target-glob-pattern Path to files or glob pattern. If using glob pattern, wrap in single
quotes.
Options:
-d, --dry dry run (no changes are made to files) (default: false)
-v, --verbose <level> Show more information about the transform process (choices: "0", "1",
"2", default: "0")
-l, --log-file [path] Write logs to a file. If option is set but no path is provided, logs are
written to ember-data-codemods.log
-i, --ignore <ignore-glob-pattern...> Ignores the given file or glob pattern. If using glob pattern, wrap in
single quotes.
--input-dir <path> Input directory containing mixins (default: "./app/mixins")
--output-dir <path> Output directory for traits (default: "./app/traits")
--config <path> Path to configuration file
-h, --help display help for command
This codemod transforms EmberData models and mixins into WarpDrive's schema format, generating:
LegacyResourceSchema# Transform all models and mixins in your app (batch mode)
npx @ember-data/codemods apply migrate-to-schema ./app
# Transform with custom output directory
npx @ember-data/codemods apply migrate-to-schema \
--output-dir './app/data/schemas' \
./app
# Transform only models
npx @ember-data/codemods apply migrate-to-schema \
--models-only \
./app
# Transform specific model files
npx @ember-data/codemods apply model-to-schema './app/models/**/*.{js,ts}'
# Transform specific mixin files
npx @ember-data/codemods apply mixin-to-schema './app/mixins/**/*.{js,ts}'
# Use a configuration file for complex setups
npx @ember-data/codemods apply migrate-to-schema \
--config './schema-migration.config.json' \
./app
For complex projects, you can use a JSON configuration file:
{
"$schema": "./tools/warp-drive-codemod/config-schema.json",
"version": "1.0.0",
"description": "Configuration for MyClient WarpDrive migration",
"dryRun": false,
"verbose": false,
"debug": false,
"mirror": true,
"emberDataImportSource": "@my-org/warp-drive/v1/model",
"intermediateModelPaths": [
"@my-org/client-core/core/custom-model",
"my-client/core/base-model",
],
"modelImportSource": "my-client/models",
"mixinImportSource": "my-client/mixins",
"modelSourceDir": "./apps/client/app/models",
"mixinSourceDir": "./apps/client/app/mixins",
"additionalModelSources": [
{
"pattern": "@my-org/client-core/core/custom-model",
"dir": "libraries/client-core/package/src/core/custom-model"
}
],
"additionalMixinSources": [
{
"pattern": "@my-org/client-core/mixins/*",
"dir": "libraries/client-core/package/src/mixins/*"
},
{
"pattern": "@my-org/schema-decorators/mixins/*",
"dir": "libraries/schema-decorators/mixins/*"
}
],
"resourcesImport": "my-client/data/resources",
"traitsDir": "./apps/client/app/data/traits",
"traitsImport": "my-client/data/traits",
"extensionsDir": "./apps/client/app/data/extensions",
"extensionsImport": "my-client/data/extensions",
"resourcesDir": "./apps/client/app/data/resources"
}
See packages/codemods/src/schema-migration/config-schema.json for full configuration options.
Before (EmberData Model):
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
export default class User extends Model {
@attr('string') declare name: string;
@attr('string') declare email: string;
@belongsTo('company', { async: false }) declare company: Company;
@hasMany('project', { async: true }) declare projects: Project[];
get displayName() {
return this.name || this.email;
}
async updateProfile(data) {
this.setProperties(data);
return this.save();
}
}
After (Generated Schema):
// app/schemas/user.schema.ts
export const UserSchema = {
type: 'user',
fields: {
name: { kind: 'attribute', type: 'string' },
email: { kind: 'attribute', type: 'string' },
company: { kind: 'belongsTo', type: 'company', options: { async: false } },
projects: { kind: 'hasMany', type: 'project', options: { async: true } }
}
};
Generated Extension:
// app/extensions/user.ts
export class UserExtension {
get displayName() {
return this.name || this.email;
}
async updateProfile(data) {
this.setProperties(data);
return this.save();
}
}
Generated Types:
// app/schemas/user.schema.types.ts
export interface User {
[Type]: 'user';
name: string;
email: string;
company: Company;
projects: Project[];
}
npx @ember-data/codemods apply legacy-compat-builders --help
Usage: @ember-data/codemods apply legacy-compat-builders [options] <target-glob-pattern...>
Updates legacy store methods to use `store.request` and `@ember-data/legacy-compat/builders` instead.
Arguments:
target-glob-pattern Path to files or glob pattern. If using glob pattern, wrap in single
quotes.
Options:
-d, --dry dry run (no changes are made to files) (default: false)
-v, --verbose <level> Show more information about the transform process (choices: "0", "1",
"2", default: "0")
-l, --log-file [path] Write logs to a file. If option is set but no path is provided, logs are
written to ember-data-codemods.log
-i, --ignore <ignore-glob-pattern...> Ignores the given file or glob pattern. If using glob pattern, wrap in
single quotes.
--store-names <store-name...> Identifier name associated with the store. If overriding, it is
recommended that you include 'store' in your list. (default: ["store"])
--method, --methods <method-name...> Method name(s) to transform. By default, will transform all methods.
(choices: "findAll", "findRecord", "query", "queryRecord", "saveRecord")
-h, --help display help for command
findAll// before
const posts = await store.findAll<Post>('post');
// after
import { findAll } from '@ember-data/legacy-compat/builders';
const { content: posts } = await store.request<Post[]>(findAll<Post>('post'));
findRecord// before
const post = await store.findRecord<Post>({ type: 'post', id: '1' });
// after
import { findRecord } from '@ember-data/legacy-compat/builders';
const { content: post } = await store.request<Post>(findRecord<Post>({ type: 'post', id: '1' }));
NOTE: This codemod will not transform store.findRecord calls with a 'preload' option set. This option is not supported by the legacy compat builders.
query// before
const posts = await store.query<Post>('post', { id: '1' });
// after
import { query } from '@ember-data/legacy-compat/builders';
const { content: posts } = await store.request<Post[]>(query<Post>('post', { id: '1' }));
queryRecord// before
const post = await store.queryRecord<Post>('post', { id: '1' });
// after
import { queryRecord } from '@ember-data/legacy-compat/builders';
const { content: post } = await store.request<Post>(queryRecord<Post>('post', { id: '1' }));
saveRecord// before
const post = store.createRecord<Post>('post', { name: 'Krystan rules, you drool' });
const savedPostWithGeneric = await store.saveRecord<Post>(post);
const savedPostNoGeneric = await store.saveRecord(post);
// after
import { saveRecord } from '@ember-data/legacy-compat/builders';
const post = store.createRecord<Post>('post', { name: 'Krystan rules, you drool' });
const { content: savedPostWithGeneric } = await store.request<Post>(saveRecord(post));
const { content: savedPostNoGeneric } = await store.request(saveRecord(post));
awaitCalls to legacy store methods that are not currently awaited will not be transformed. In order to provide feature parity with the legacy method, we need to access the content property from Future returned by store.request. In order to do this, we need to await store.request, but we can't safely add await with a codemod as we don't know if the consuming code will be able to handle the change.
There is one exception to this rule. In the case where a route's model hook returns a call to a legacy store method, the codemod will transform the legacy store method and will add the await keyword.
GJS and GTS files are not currently supported. PRs welcome! 🧡
FAQs
Codemods for WarpDrive/EmberData paradigms
The npm package @ember-data/codemods receives a total of 9 weekly downloads. As such, @ember-data/codemods popularity was classified as not popular.
We found that @ember-data/codemods demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.

Security News
Socket CEO Feross Aboukhadijeh joins Insecure Agents to discuss CVE remediation and why supply chain attacks require a different security approach.

Security News
Tailwind Labs laid off 75% of its engineering team after revenue dropped 80%, as LLMs redirect traffic away from documentation where developers discover paid products.