As mentioned in Getting Started, there are several ways to define the entry property in your webpack configuration. This page walks through the ways you can configure entry and explains why each may be useful.
In simple terms, an entry point tells webpack where to start building its internal dependency graph. Starting from this file, webpack recursively follows every imported module and asset to determine what belongs in the final bundle.
The result of this process is later written to disk according to the output configuration, which controls where and how the bundled files are emitted.
[!TIP] When you run webpack without a configuration file, the entry defaults to
'./src/index.js'. If that file is missing — even when yoursrc/directory exists — webpack throws:
ERROR in Entry module not found: Error: Can't resolve './src'The error mentions
'./src'rather than'./src/index.js'because webpack resolves the directory first and then fails to findindex.jsinside it. To use a different entry filename, configure theentryoption as shown in the sections below.
Usage: entry: string | [string]
string: a single entry file.[string]: multiple entry files.
export default {
entry: './path/to/my/entry/file.js',
};The single entry syntax for the entry property is shorthand for:
export default {
entry: {
main: './path/to/my/entry/file.js',
},
};You can also pass an array of file paths to the entry property, which creates what is known as a "multi-main entry". This is useful when you want to inject several dependent files together and graph their dependencies into a single chunk.
export default {
entry: ['./src/file_1.js', './src/file_2.js'],
};When an array is provided for an entry point, webpack still creates a single entry chunk. All modules in the array are loaded in the given order and combined into the same dependency graph.
This pattern is commonly used to inject extra code before the main application entry — such as polyfills or development-only tooling — without manually importing it in the application source.
Example: injecting a polyfill
export default {
entry: {
main: ['@babel/polyfill', './src/index.js'],
},
};The single entry syntax is a great choice when you want to quickly set up a webpack configuration for an application or tool with one entry point, such as a library. However, it offers little flexibility for extending or scaling your configuration.
Usage: entry: { <entryChunkName> string | [string] } | {}
<entryChunkName>: the name of the entry chunk.string: a single entry file.[string]: multiple entry files.{}: an empty object.
export default {
entry: {
app: './src/app.js',
adminApp: './src/adminApp.js',
},
};The object syntax is more verbose, but it is the most scalable way to define entries in your application.
[!TIP] "Scalable webpack configurations" are ones that can be reused and combined with other partial configurations. This is a popular technique for separating concerns by environment, build target, and runtime. The partial configurations are then merged with specialized tools like webpack-merge.
[!TIP] You can pass an empty object
{}toentrywhen your only entry points are generated by plugins.
An object describing an entry point. You can specify the following properties:
dependOn: the entry points that this entry point depends on. They must be loaded before this entry point is loaded.filename: the name of each output file on disk.import: the module(s) loaded at startup.library: specifies library options to bundle a library from the current entry.runtime: the name of the runtime chunk. When set, a new runtime chunk is created. Since webpack 5.43.0, it can be set tofalseto avoid creating a new runtime chunk.publicPath: a public URL for this entry's output files when they are referenced in a browser. See also output.publicPath.
export default {
entry: {
a2: 'dependingfile.js',
b2: {
dependOn: 'a2',
import: './src/app.js',
},
},
};runtime and dependOn must not be used together on a single entry, so the following configuration is invalid and throws an error:
export default {
entry: {
a2: './a',
b2: {
runtime: 'x2',
dependOn: 'a2',
import: './b',
},
},
};runtime must not point to an existing entry point name either. The configuration below throws an error:
export default {
entry: {
a1: './a',
b1: {
runtime: 'a1',
import: './b',
},
},
};Finally, dependOn must not be circular. The following example also throws an error:
export default {
entry: {
a3: {
import: './a',
dependOn: 'b3',
},
b3: {
import: './b',
dependOn: 'a3',
},
},
};Here are some common entry configurations and their real-world use cases.
export default {
entry: {
main: './src/app.js',
vendor: './src/vendor.js',
},
};When building in production mode:
export default {
output: {
filename: '[name].[contenthash].bundle.js', // e.g. main.abc123.bundle.js, vendor.abc123.bundle.js
},
};When building in development mode:
export default {
output: {
filename: '[name].bundle.js', // e.g. main.bundle.js, vendor.bundle.js
},
};What does this do? It tells webpack that we want two separate entry points, as in the example above.
Why? With this setup, you can import libraries or files that rarely change (such as Bootstrap, jQuery, or images) inside vendor.js, and they will be bundled together into their own chunk. Because the content hash stays the same, the browser can cache them separately, reducing load time.
[!TIP] In webpack versions earlier than 4, it was common to add vendors as a separate entry point so they would be compiled into a separate file (in combination with the
CommonsChunkPlugin).This is discouraged in webpack 4 and later. Instead, the
optimization.splitChunksoption takes care of separating vendor and app modules into a separate file. Do not create an entry for vendors or anything else that is not the starting point of execution.
export default {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js',
},
};What does this do? It tells webpack that we want three separate dependency graphs, as in the example above.
Why? In a multi-page application, the server fetches a new HTML document for each page. The page reloads that document and its assets are re-downloaded. This gives us a unique opportunity to use techniques like optimization.splitChunks to create bundles of code shared across pages. Multi-page applications that reuse a lot of code between entry points benefit greatly from these techniques as the number of entry points grows.
[!TIP] As a rule of thumb, use exactly one entry point per HTML document. See the issue described here for more details.