Table of Contents
Why Project Organization Matters
When you start writing more than a few MATLAB files, the way you organize your work becomes as important as the code itself. A clear project structure makes it easier to find files, understand what your own code does after some time has passed, and share work with others or with your future self. MATLAB relies heavily on folders and the search path, so a bit of planning at the beginning of a project will save you many confusing errors later.
In this chapter, the focus is on how to structure your MATLAB projects using folders and files. The goal is not to make rigid rules, but to give you simple patterns that you can adapt to projects of different sizes.
Defining a MATLAB Project
A MATLAB project is simply a set of related files that belong together. These might be scripts, functions, data files, figures, or documentation that all serve the same task or problem. For a small task, everything might live in a single folder. For anything bigger, it helps to treat that folder as the root of your project.
To start a new project, create a new folder from the Current Folder browser, or with a command like:
mkdir('MyFirstProject')
cd('MyFirstProject')Consider this folder the top level of the project. All code, data, and results that belong to the project should live inside this folder in some sensible structure. Try to avoid spreading a single project over many unrelated folders on your computer, because it quickly becomes difficult to understand which file is used where.
A Simple Folder Structure for Beginners
As your projects grow, you can divide the top level into subfolders with clear purposes. One simple and effective pattern is to separate code, raw data, results, and documentation. For example:
MyFirstProject/
code/
data/
results/
docs/You can create these folders from MATLAB:
mkdir('code')
mkdir('data')
mkdir('results')
mkdir('docs')
The exact names are not important, but consistency is. For example, you might decide that all your projects always have a code folder where scripts and functions live, and a data folder that contains input files. This makes it easier to move between projects, because you know where to look for things.
Within code, you might later add subfolders for specific topics, such as:
MyFirstProject/
code/
preprocessing/
analysis/
plotting/Do not create too many levels of folders at first. Start with a simple structure and only introduce new subfolders when it is clearly helpful.
Separating Code, Data, and Results
Keeping code, input data, and generated results separate has several advantages. It prevents you from accidentally overwriting important data files, and it makes it easier to clean up and rerun your project from scratch.
Place your main scripts and functions in the code folder or a similar dedicated folder. Place input datasets, configuration files, and external resources in the data folder. When your scripts produce outputs such as processed data, figures, or reports, save them in a results or output folder.
For example, inside your main script you might write:
% Read raw data
T = readtable(fullfile('data', 'measurements.csv'));
% Do some analysis
% ...
% Save results
save(fullfile('results', 'analysisResults.mat'), 'T');
By always using data and results relative to your project root, you avoid confusion about where files are read from and written to. This is especially valuable when you move the project to another computer or share it with someone else.
Using Logical Names for Files and Folders
Meaningful, consistent names make your project easy to understand. For folders, choose names that describe their purpose, such as code, data, results, tests, or docs. Avoid vague names like stuff or temp for anything that is not truly temporary.
For files, try to use names that indicate what the file does. For example, a script that imports and cleans raw sensor data could be named importSensorData.m rather than script1.m. A function that computes an average could be called computeAverage.m instead of myfunc.m. When filenames are descriptive, you need fewer comments to remember the purpose of each file.
If you create many versions of the same file, think carefully about how you name them. Instead of copying analysis.m into analysis_new.m or analysis_final.m, consider making clear changes within a single file and using version control tools separately. If you really need multiple variants, adopt a clear naming pattern such as analysis_v1, analysis_v2, and so on, but try not to rely on this as your main way to manage changes.
Main Scripts and Entry Points
Many projects benefit from having one or a few main scripts that serve as entry points. An entry point is a script that a user can run to execute a complete task, such as running a full analysis or generating all figures.
You can place such a script at the top level of the project:
MyFirstProject/
runAnalysis.m
code/
data/
results/
The script runAnalysis.m can then call functions from the code folder. For example:
% runAnalysis.m
addpath('code');
% Load data and run steps
rawData = loadRawData();
cleaned = cleanData(rawData);
results = analyze(cleaned);
plotResults(results);
In larger projects, you may have several entry scripts, each focusing on a specific purpose such as runAllTests.m or makeAllFigures.m. The important idea is that a new user, including your future self, can quickly see which files to run to reproduce your work.
Relative Paths Inside a Project
When working inside a project, it is better to build file locations using relative paths that start from the project folder, rather than absolute paths that include the full directory of your computer. Absolute paths tend to break when the project is moved to another location or used on another system.
You can obtain the path to the folder that contains a script by using:
projectFolder = fileparts(mfilename('fullpath'));
From there, construct paths with fullfile:
dataFolder = fullfile(projectFolder, 'data');
resultsFolder = fullfile(projectFolder, 'results');
inputFile = fullfile(dataFolder, 'measurements.csv');
outputFile = fullfile(resultsFolder, 'analysisResults.mat');Using this pattern, the script will work no matter where the project folder is placed, as long as the internal structure remains the same. This is especially useful when combining project organization with version control or when sharing projects as compressed archives.
Organizing Functions into Folders
When you start writing more functions, placing all of them in a single folder can become messy. Grouping related functions into subfolders can make your code easier to navigate. For example, you might use:
MyFirstProject/
code/
io/
processing/
plotting/
Place functions that handle reading and writing data in the io folder, functions that transform or analyze data in processing, and functions that create figures in plotting. This way, when you need to modify how data is read, you know where to look.
You can add these folders to the path at the beginning of your main script:
projectFolder = fileparts(mfilename('fullpath'));
codeFolder = fullfile(projectFolder, 'code');
addpath(codeFolder);
addpath(fullfile(codeFolder, 'io'));
addpath(fullfile(codeFolder, 'processing'));
addpath(fullfile(codeFolder, 'plotting'));This pattern clearly shows which parts of your project contain executable code and which are data or results.
Keeping Temporary and Generated Files Under Control
Many analyses generate intermediate files, temporary data, or automatic outputs that you do not want to track by hand. A clean structure for these files makes it easier to delete and recompute them when needed.
You can dedicate a temp folder or a subfolder inside results for intermediate outputs throughout your project. For example:
MyFirstProject/
results/
figures/
summaries/
temp/
In your scripts, write temporary outputs to that temp folder. If something goes wrong or you want to start over, you know that it is safe to clear that folder without losing original data or important results. This is much safer than scattering temporary files across arbitrary locations.
Adding Documentation Inside the Project
Good organization includes notes that explain the structure and purpose of your project. A simple way to do this is to maintain a short text or MATLAB Live Script in the root folder that describes how the project is arranged and how to run it.
For example, create a README.mlx or README.txt that briefly lists:
The purpose of the project.
The main scripts to run.
The meaning of the top level folders.
If you use a script as a readme, you can include comments at the top, such as:
% README for MyFirstProject
%
% Folders:
% code/ - scripts and functions
% data/ - input data files (not modified)
% results/ - generated outputs and figures
%
% Main entry:
% runAnalysis.mEven a small amount of this type of documentation can save a lot of time when you return to a project after some months.
Keeping the MATLAB Path Clean
Since folder organization and the MATLAB path interact closely, it is helpful to limit how many folders you add permanently to the path. Instead of adding every new project folder to your default path, consider adding paths at runtime from within your main script using addpath, as illustrated earlier, and optionally removing them with rmpath when you are finished.
This approach keeps different projects isolated from each other. Two projects can have functions with the same name in their own code folders, and you choose which one to use simply by running the appropriate project entry script that adds the correct folders to the path.
Important points to remember:
Organize each MATLAB project in its own top level folder, and keep related files together.
Separate code, input data, and generated results into different folders.
Use relative paths built with fullfile so your project works when moved to a new location.
Group related functions in subfolders inside a code area, and add them to the path from your main scripts.
Document the project structure and main entry scripts with a simple README file.
Keep the MATLAB path clean by adding and removing project folders at runtime instead of changing the global path for everything.