Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5c1372a
feat(template)!: unify JS/TS templates
erickzhao Apr 20, 2026
e43f696
Merge branch 'next' into template-unification
erickzhao Apr 20, 2026
59c6f65
hmm
erickzhao Apr 20, 2026
7bf5ea7
add slow tests back
erickzhao Apr 20, 2026
984f192
22.13.0 minimum
erickzhao Apr 20, 2026
bf8f781
add missing deps
erickzhao Apr 20, 2026
49ec177
use project oxfmt
erickzhao Apr 20, 2026
b7d71b1
more fixes
erickzhao Apr 21, 2026
e66f3db
remove knip references to old template
erickzhao Apr 21, 2026
869ecab
add missing deps
erickzhao Apr 21, 2026
b7d24fd
tests/warnings
erickzhao Apr 21, 2026
180aca6
Merge branch 'next' into template-unification
erickzhao Apr 21, 2026
7debf61
Merge branch 'next' into template-unification
erickzhao May 21, 2026
488fc81
huh
erickzhao May 21, 2026
63ac87b
another removal
erickzhao May 21, 2026
11d544e
more fixes
erickzhao May 22, 2026
d487bdf
Update package.json
erickzhao May 22, 2026
a7e02f3
remove fs-extra
erickzhao May 22, 2026
688c027
Merge branch 'template-unification' of github.com:electron/forge into…
erickzhao May 22, 2026
57dd0ab
use utils :)
erickzhao May 22, 2026
69bc0cb
revert vitest exclude for now
erickzhao May 26, 2026
41bb614
address comments
erickzhao May 26, 2026
84c6689
format file too
erickzhao May 28, 2026
2082b7d
fixup
erickzhao Jun 5, 2026
e8819df
remove TS-specific comment from webpack main.ts template
erickzhao Jun 5, 2026
1a9807f
fix(template): close base+typescript guard bypass and drop orphaned l…
erickzhao Jun 9, 2026
50b059d
Merge branch 'next' into template-unification
claude Jul 6, 2026
5e81b01
fix(create-electron-app): prompt for a bundler when --typescript is p…
claude Jul 6, 2026
0b64f19
refactor(template): compute dev dependencies from init options instea…
claude Jul 6, 2026
c005de8
fix(template): surface oxfmt errors, guard old Node.js versions, rest…
claude Jul 6, 2026
a333f11
test: cover base template TypeScript rejection and removed template r…
claude Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22.12
22.13
14 changes: 0 additions & 14 deletions knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,24 +142,10 @@
"entry": ["spec/**/*.spec.ts"],
"project": ["src/**/*.ts!", "spec/**/*.ts"]
},
"packages/template/vite-typescript": {
"entry": ["spec/**/*.spec.ts"],
"project": ["src/**/*.ts!", "spec/**/*.ts"]
},
"packages/template/webpack": {
"entry": ["spec/**/*.spec.ts"],
"project": ["src/**/*.ts!", "spec/**/*.ts"]
},
"packages/template/webpack-typescript": {
"entry": ["spec/**/*.spec.ts"],
"project": ["src/**/*.ts!", "spec/**/*.ts"],
"ignoreDependencies": [
"@electron-forge/maker-.*",
"@electron-forge/plugin-webpack",
"webpack",
"listr2"
]
},
"packages/utils/core-utils": {
"entry": ["src/remote-rebuild.ts!", "spec/**/*.spec.ts"],
"project": ["src/**/*.ts!", "spec/**/*.ts"]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "MIT",
"type": "module",
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"resolutions": {
"ajv@8.17.1": "^8.18.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/api/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"semver": "^7.2.1"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"funding": [
{
Expand Down
2 changes: 1 addition & 1 deletion packages/api/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"listr2": "^7.0.2"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"funding": [
{
Expand Down
4 changes: 1 addition & 3 deletions packages/external/create-electron-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@
"author": "Samuel Attard",
"license": "MIT",
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/core-utils": "workspace:*",
"@electron-forge/shared-types": "workspace:*",
"@electron-forge/template-base": "workspace:*",
"@electron-forge/template-vite": "workspace:*",
"@electron-forge/template-vite-typescript": "workspace:*",
"@electron-forge/template-webpack": "workspace:*",
"@electron-forge/template-webpack-typescript": "workspace:*",
"@inquirer/prompts": "^6.0.1",
"@listr2/prompt-adapter-inquirer": "^2.0.22",
"@malept/cross-spawn-promise": "^2.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,18 @@ describe('findTemplate', () => {
'Failed to locate custom template: "non-existent-template".',
);
});

describe('removed language-specific templates', () => {
it.each([
['vite-typescript', 'vite'],
['webpack-typescript', 'webpack'],
])(
'should redirect "%s" to the --typescript flag',
async (template, bundler) => {
await expect(findTemplate(template)).rejects.toThrowError(
`The "${template}" template no longer exists. Use "--template ${bundler} --typescript" instead.`,
);
},
);
});
});
43 changes: 32 additions & 11 deletions packages/external/create-electron-app/src/create-electron-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const initCommand = program
'--package-manager [name]',
'Set a specific package manager to use for your Forge project. Supported package managers are `npm`, `pnpm`, and `yarn`. You can also specify an exact version to use (e.g. `yarn@1.22.22`).',
)
.option('--typescript', 'Use TypeScript in the template.')
.action(async (dir) => {
const options = initCommand.opts();
const tasks = new Listr<InitOptions>(
Expand All @@ -52,18 +53,40 @@ const initCommand = program
initOpts.copyCIFiles = Boolean(options.copyCiFiles);
initOpts.force = Boolean(options.force);
initOpts.skipGit = Boolean(options.skipGit);
initOpts.typescript = Boolean(options.typescript);
Comment thread
erickzhao marked this conversation as resolved.
initOpts.dir = resolveWorkingDir(dir, false);
initOpts.electronVersion = options.electronVersion ?? 'latest';
initOpts.packageManager = options.packageManager ?? 'npm@latest';
},
},
{
task: async (initOpts, task): Promise<void> => {
if (
Object.keys(options).length > 0 ||
process.env.CI ||
!process.stdout.isTTY
) {
const canPrompt = !process.env.CI && process.stdout.isTTY;

if (Object.keys(options).length > 0 || !canPrompt) {
// `--typescript` requires a bundler-based template, so if no
// `--template` was passed, prompt for a bundler when possible.
// In non-interactive contexts, the base template rejects the
// flag with an actionable error instead.
if (canPrompt && options.typescript && !options.template) {
const prompt = task.prompt(ListrInquirerPromptAdapter);
initOpts.template = await prompt.run<Prompt<string, any>>(
select,
{
message: 'Select a bundler',
choices: [
{
name: 'Vite (Experimental)',
value: 'vite',
},
{
name: 'webpack',
value: 'webpack',
},
],
},
);
}
return;
}

Expand Down Expand Up @@ -120,29 +143,27 @@ const initCommand = program
},
);

let language: string | undefined;

if (bundler !== 'base') {
language = await prompt.run<Prompt<string | undefined, any>>(
initOpts.typescript = await prompt.run<Prompt<boolean, any>>(
select,
{
message: 'Select a programming language',
choices: [
{
name: 'JavaScript',
value: undefined,
value: false,
},
{
name: 'TypeScript',
value: 'typescript',
value: true,
},
],
},
);
}

initOpts.packageManager = packageManager;
initOpts.template = `${bundler}${language ? `-${language}` : ''}`;
initOpts.template = bundler;

// TODO: add prompt for passing in an exact version as well
initOpts.electronVersion = await prompt.run<Prompt<string, any>>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ export const findTemplate = async (
}
}
if (!foundTemplate) {
// Only the bundled `vite`/`webpack` templates were unified behind the
// `--typescript` flag, so only redirect the old short-form names. Skip
// absolute paths and third-party templates, which don't honor the flag.
if (
!isAbsolutePath &&
(template === 'vite-typescript' || template === 'webpack-typescript')
) {
const bundler = template.replace(/-typescript$/, '');
throw new Error(
`The "${template}" template no longer exists. Use "--template ${bundler} --typescript" instead.`,
);
}
throw new Error(`Failed to locate custom template: "${template}".`);
} else {
d(`found template module at: ${foundTemplate.path}`);
Expand Down
20 changes: 17 additions & 3 deletions packages/external/create-electron-app/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export interface InitOptions {
* Force a package manager to use (npm|yarn|pnpm).
*/
packageManager?: string;
/**
* Whether to use TypeScript in the template.
*/
typescript?: boolean;
}

async function validateTemplate(
Expand Down Expand Up @@ -95,6 +99,7 @@ export async function init({
skipGit = false,
electronVersion = 'latest',
packageManager,
typescript = false,
}: InitOptions): Promise<void> {
d(`Initializing in: ${dir}`);

Expand Down Expand Up @@ -173,6 +178,7 @@ export async function init({
const tasks = await templateModule.initializeTemplate(dir, {
copyCIFiles,
force,
typescript,
});
if (tasks) {
return task.newListr(tasks, { concurrent: false });
Expand Down Expand Up @@ -224,13 +230,21 @@ export async function init({
title: 'Installing development dependencies',
task: async ({ pm }, task) => {
d('installing devDependencies');
if (templateModule.devDependencies?.length) {
task.output = `${pm.executable} ${pm.install} ${pm.dev} ${templateModule.devDependencies.join(' ')}`;
const devDependencies =
templateModule.getDevDependencies?.({
copyCIFiles,
force,
typescript,
}) ??
templateModule.devDependencies ??
[];
if (devDependencies.length) {
task.output = `${pm.executable} ${pm.install} ${pm.dev} ${devDependencies.join(' ')}`;
}
await installDependencies(
pm,
dir,
templateModule.devDependencies || [],
devDependencies,
DepType.DEV,
);
},
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/appx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/core-utils": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/shared-types": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/deb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/maker-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/dmg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/maker-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/flatpak/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/maker-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/msix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/core-utils": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/pkg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/maker-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/rpm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/maker-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/snap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/maker-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/squirrel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"exports": "./dist/MakerSquirrel.js",
"typings": "dist/MakerSquirrel.d.ts",
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/core-utils": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/wix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"exports": "./dist/MakerWix.js",
"typings": "dist/MakerWix.d.ts",
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/core-utils": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/maker/zip/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"vitest": "catalog:"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/core-utils": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/auto-unpack-natives/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"exports": "./dist/AutoUnpackNativesPlugin.js",
"typings": "dist/AutoUnpackNativesPlugin.d.ts",
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/plugin-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"exports": "./dist/Plugin.js",
"typings": "dist/Plugin.d.ts",
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/shared-types": "workspace:*"
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/fuses/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@electron/fuses": "^2.0.0"
},
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/plugin-base": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/local-electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"exports": "./dist/LocalElectronPlugin.js",
"typings": "dist/LocalElectronPlugin.d.ts",
"engines": {
"node": ">= 22.12.0"
"node": ">= 22.13.0"
},
"dependencies": {
"@electron-forge/plugin-base": "workspace:*",
Expand Down
Loading
Loading