What a spec file does and why you need it

A spec file is a Python script that tells PyInstaller exactly how to package your program — which files to include, what icon to use, whether to hide the console window, and dozens of other settings. Instead of typing a long command every time you build, you create the spec file once and reuse it.

PyInstaller generates a spec file automatically the first time you run it on your program. That file sits in your project folder with a name like myprogram.spec. You can edit it to change how PyInstaller behaves, then run PyInstaller against the spec file instead of against your Python script directly.

This matters because building the same program multiple times with different settings — or sharing your build setup with teammates — becomes much simpler. The spec file is plain text, so you can version control it, edit it in any text editor, and know exactly what settings were used to create each build.

Key Takeaways

  • Generate a spec file by running pyi-makespec yourscript.py in your terminal or command prompt, which creates a file named yourscript.spec in your current folder.
  • Edit the spec file in any text editor to change settings like hidden imports, data files, icons, and whether the console window appears.
  • Build your program from the spec file by running pyinstaller yourscript.spec instead of pyinstaller yourscript.py.
  • The spec file is a Python script itself, so you can use variables and logic inside it to handle different build scenarios.
  • Keep your spec file in version control so you and your team always build the same way.

Creating a spec file from your Python script

Open your terminal or command prompt and navigate to the folder where your Python script lives. Run this command:

pyi-makespec yourscript.py

Replace yourscript.py with the actual name of your main Python file. PyInstaller creates a new file in that same folder called yourscript.spec. Open it in any text editor — Notepad, VS Code, or whatever you use for code.

The spec file is a Python script that imports PyInstaller's internal functions and defines how your program should be packaged. You do not need to understand every line, but the main sections are readable: Analysis (what files to include), PYZ (the Python archive), EXE (the executable settings), and COLLECT (what goes in the output folder).

Common settings to change in your spec file

The spec file has many options. Here are the ones you will change most often:

Hidden imports: If your program imports a module that PyInstaller does not detect automatically, add it to the hiddenimports list. For example, if you use import requests but PyInstaller misses it, find the line that says hiddenimports=[], and change it to hiddenimports=['requests'],. Add multiple imports as a comma-separated list.

Data files: If your program needs to read files like images, config files, or data folders, add them to the datas list. The format is a tuple: datas=[('path/to/your/folder', 'folder_name_in_bundle'),]. The first path is where the files are now; the second is where they will be inside your packaged program.

Icon: Find the line that creates the EXE object and add icon='path/to/your/icon.ico'. The icon file must be in ICO format on Windows, ICNS on macOS, or PNG on Linux.

Console window: In the EXE section, change console=True to console=False if you do not want a black command window to appear when users run your program.

Building your program from the spec file

Once you have edited the spec file, build your program by running:

pyinstaller yourscript.spec

PyInstaller reads the spec file and builds your program according to those settings. The output appears in a dist folder in your project directory. On Windows, you will find an EXE file; on macOS, an app bundle; on Linux, an executable.

If you make changes to the spec file, just run the same command again. PyInstaller rebuilds from scratch, so you do not have to delete old builds or worry about leftover files.

Handling multiple builds with one spec file

You can use Python logic inside the spec file to handle different build scenarios. For example, you might want a debug build with the console visible and a release build without it.

At the top of the spec file, add a variable like DEBUG = False. Then in the EXE section, use console=DEBUG instead of a hard-coded True or False. Edit that one line at the top to switch between builds, or pass it as a command-line argument if you want to get more advanced.

You can also create separate spec files for different purposes — myprogram-debug.spec and myprogram-release.spec — and keep them both in version control. This makes it clear which settings go with which build.

Troubleshooting common spec file problems

If PyInstaller says it cannot find a module, add it to hiddenimports in the spec file. This happens most often with modules that use dynamic imports or are installed as plugins.

If your program runs fine in Python but crashes when packaged, check the datas list. Your program is probably looking for a file that did not get bundled. Run your packaged program from the command line to see the error message, which usually tells you what file is missing.

If the icon does not appear, make sure the path to the ICO file is correct and that the file actually exists. Relative paths in the spec file are relative to the folder where the spec file sits, not your current working directory.

If your program is much larger than expected, you may have included unnecessary files in datas. Be specific about what folders you include — do not include your entire project folder if you only need one subfolder.

Sharing your spec file with teammates

Commit your spec file to version control alongside your Python code. When a teammate clones your repository, they can build your program the same way you do by running pyinstaller yourscript.spec. This ensures everyone produces identical builds.

If your spec file references paths that differ between machines — like a data folder in a different location on macOS versus Windows — use relative paths or environment variables. For example, instead of hardcoding '/Users/yourname/data', use os.path.join(os.path.dirname(SPEC), 'data') to reference a folder relative to the spec file itself.

Frequently Asked Questions

Can I edit the spec file while PyInstaller is running?

No. Close any builds that are in progress, edit the spec file, and then run PyInstaller again. PyInstaller reads the entire spec file before it starts building, so changes made during a build will not take effect until the next run.

What happens if I delete the spec file?

You can regenerate it by running pyi-makespec yourscript.py again. However, you will lose any custom settings you added. Keep your spec file in version control so you do not accidentally lose your build configuration.

Do I need to install PyInstaller separately from my program?

Yes. PyInstaller is a separate tool that you install on your development machine with pip install pyinstaller. Your packaged program does not include PyInstaller — it only includes your Python code and the Python runtime.

Can I use the same spec file on Windows, macOS, and Linux?

Mostly yes, but some settings are platform-specific. The icon format differs, and paths may need adjustment. Use conditional logic in the spec file to handle platform differences, or create separate spec files for each operating system.

Why is my packaged program so much slower than running the Python script directly?

PyInstaller bundles the Python interpreter and all your dependencies into one file, which takes longer to start up. The program itself runs at normal speed once it starts. If startup time matters, you can use the --onefile option in the spec file, though this makes the initial startup even slower — use --onedir instead for faster startup.