How to Package Your Code and Data for Maximum Reproducibility
By Dr. Zubair Khalid, DVM, MS, PhD ·

By the end of this guide you will be able to assemble a complete reproducibility package for one of your own analyses: a version-controlled project folder, a pinned dependency environment, a documented dataset, an executable pipeline that runs from raw input to final figure, and a permanent archive with a DOI that your availability statement can point to. You will also know how to verify the package actually works on a clean machine before you submit a manuscript.
To follow the walkthrough you need a computer with R (version 4.x) or Python (version 3.10 or newer), Git installed, and a free account on GitHub and on a data repository such as Zenodo, OSF, or Dryad. No prior experience with packaging is assumed.
Why Packaging Matters: The Current State of Code and Data Sharing
Reproducible research means that another person, working independently, can rerun your analysis on your data and reach your reported results. A large Delphi consensus study across researchers, editors, publishers, funders, and policymakers framed this as the ability of others to independently verify scientific findings by following the same methods and data, and identified it as a core pillar of research integrity [1].
The gap between that ideal and daily practice is wide. In a meta-research study of 400 aging research articles funded by the Nathan Shock Centers, half had no data availability statement at all, and 92% had no code availability statement. Even among articles that claimed materials were open, the deposited data could actually be located only 63% of the time [2]. A large-language-model-assisted scoping review of 3,967 clinical prediction model studies found that only 12.2% included any code-sharing statement, and among the repositories that were shared, the authors documented substantial heterogeneity in reproducibility features such as documentation, dependency specification, and executable structure [3]. In real-world evidence research published in one population data science journal, none of 41 eligible articles met all five open science domains the reviewers assessed, and only 34% included a data availability statement [4].
These numbers point to a consistent pattern. The problem is rarely a refusal to share. It is that packages, when they exist at all, are incomplete, undocumented, or broken. Policies alone do not fix this. A survey of 171 materials science journals found that nearly all now have a research data policy, but enforceable requirements remain uncommon, and expectations for research software lag far behind those for data, with limited attention to versioning, persistent identifiers, dependency disclosure, and reproducible execution environments [5]. Funders show a similar pattern. In a scoping review of 12 major cardiovascular research funders, 67% of policy documents addressed data sharing, but requirements for code sharing were uncommon [6].
There is also good evidence that packaging works when it is enforced. When leading economics and political science journals adopted mandatory data and code sharing policies, independent teams could computationally reproduce more than 85% of published claims, and in robustness reanalyses 72% of statistically significant estimates remained significant in the same direction [7]. A well-built package is what turns "we could share if asked" into a result someone can actually verify.
What a Reproducibility Package Contains
A complete package has four components. Each one answers a specific question a reproducer will ask.
- Data answers "what went in." The actual files, or a documented procedure to obtain or reconstruct them, plus a data dictionary.
- Code answers "what was done." Every script needed to go from raw data to every reported number, table, and figure.
- Environment answers "with what software." Exact package versions, language version, and operating system details, so behavior does not change when libraries update.
- Documentation answers "how do I run this." A README with step order, expected runtime, expected output, and a license.
The FAIR principles, Findable, Accessible, Interoperable, and Reusable, were formulated for data and have since been extended to research software and to workflows. A review of reproducible metabolomics practice argues that the FAIR case applies most strongly exactly where most packages fail today, the analysis layer that turns raw files into reported results [8]. Field-specific tooling has now converged on the same design. Open preprocessing frameworks for pupillometry, for example, explicitly build on FAIR principles, follow a defined file management schema, and generate automated quality control reports that double as records for sharing [9]. The structure below follows that same logic.
Step by Step: Building the Package

Step 1. Restructure your project folder
Stop keeping analysis scripts on your desktop and data in your Downloads folder. Create a self-contained project directory with a conventional layout:
mkdir -p myproject/{data_raw,data_cleaned,R,output,figures,docs}
cd myproject
git init
Expected result:
myproject/
data_raw/ original, read-only input files
data_cleaned/ derived datasets produced by scripts, never edited by hand
R/ all analysis scripts
output/ tables, model summaries, exported numbers
figures/ every figure, regenerated by code
docs/ data dictionary, protocol, notes
The rule that makes this work is directional. Raw data flows one way, through scripts, into derived data and outputs. Nothing downstream is ever edited by hand. If you catch yourself opening a CSV in Excel to fix a value, the fix belongs in a cleaning script instead.
Commit the project to Git from the start:
git add .
git commit -m "Initial project structure"
Version control gives you traceability. Packages that embed figure code and metadata directly in analysis pipelines let reviewers trace every visualization to its generating script and regenerate figures automatically when data or methods change [10].
Step 2. Record your software environment
Dependencies are the single most common reason a shared package fails to run. A scoping review of public health database analyses found that even reporting the R version used was inconsistent across articles, which makes silent behavioral differences between package versions invisible to readers [11].
For R, use renv to capture the exact package versions your project uses:
install.packages("renv")
renv::init()
renv::snapshot()
Expected output:
* Snapshot written to '/path/to/myproject/renv.lock'
The resulting renv.lock file records your R version and the exact version of every package. A collaborator reproduces the environment with:
renv::restore()
For Python, record the environment with pip:
python -m venv .venv
source .venv/bin/activate
pip freeze > requirements.txt
A requirements.txt with pinned versions, for example pandas==2.2.1 rather than unpinned pandas, is what makes pip install -r requirements.txt reproduce your environment rather than whatever versions are current next year.
Also save a session report inside the package. In R, sessionInfo() printed to a text file in docs/ documents versions, locale, and attached packages. This takes one minute and resolves most "works on my machine" disputes.
Step 3. Document the data
Every dataset in the package needs a README and a data dictionary in docs/. The data dictionary is a table listing each variable name, its definition, its units, and its allowed values. Write it even for data you generated yourself, because in six months you are the collaborator who has forgotten the coding scheme.
Record provenance explicitly: where the raw files came from, the download date, any accession numbers, and any preprocessing applied before analysis. If the data come from a public archive, name the archive and the exact accession so a reproducer can verify the input independently.
Step 4. Decide what you can share, and at what tier

Not every dataset can be posted. Privacy constraints on clinical data are real, and approaches exist for handling them honestly. A framework developed for Japanese electronic health record narratives shows one path, generating deidentified analytic text that preserves enough context for post hoc auditing while quantifying masking rates and downstream recoverability so reviewers know exactly what was changed [12]. If you work with human data, document the deidentification pipeline as part of the package, not just the decision to withhold the raw files.
When full sharing is impossible, share at the highest tier the data support. A proposed three-tier framework for clinical trial data argues that transparency should be matched to the scientific claims a data object can support. Tier 1 comprises reduced datasets released at publication that support endpoint-level numerical reproducibility, and Tier 2 comprises fuller reproducibility packages for deeper reanalysis [13]. The practical translation: even when individual participant data cannot leave the study, an analysis-ready reduced dataset plus the full code usually can, and that combination already allows independent verification of your headline results.
Code sharing matters most in exactly these situations. Because population data research often cannot share record-level data, sharing the analytical code becomes the primary route to verifiability [4]. Your code, running on a documented data structure, lets a reviewer audit the method even when the raw records stay behind access controls.
Step 5. Make the pipeline executable end to end
Your package should have one entry point that runs everything in the correct order. A single driver script is the simplest form:
# run_all.R
source("R/01_clean_data.R")
source("R/02_descriptive_stats.R")
source("R/03_primary_model.R")
source("R/04_sensitivity_analyses.R")
source("R/05_make_figures.R")
Run it from the project root:
Rscript run_all.R
Expected output includes the printed progress of each script and, at the end, refreshed files in output/ and figures/. Every figure in your manuscript should be produced by this run. Script-based figure generation improves transparency and traceability and lets figures be regenerated automatically as data or methods change [10].
The deeper principle, articulated for metabolomics but general to computational biology, is that analyses should be executable workflows that carry FAIR practice from the data itself to the reported result, so the pipeline from raw files to final feature tables can be shared, audited, and reused [8]. Treat reporting the same way. Reporting standards work best when documentation is embedded prospectively in the analysis rather than reconstructed as a final manuscript stage, a pattern identified as a key barrier in radiological AI research [14]. The run log, the session report, and the pipeline order are your prospective documentation. Write them as you work, not the week before submission.
Step 6. Test on a clean machine
Before sharing, verify the package the way a stranger will experience it. Clone the repository into a fresh directory, restore the environment, and run the full pipeline:
git clone https://github.com/yourname/myproject.git test-clone
cd test-clone
Rscript -e "renv::restore()"
Rscript run_all.R
Success means the pipeline completes without errors and the regenerated numbers match your manuscript. If a figure changes, something was hard-coded or an output was hand-edited. Fix the script, not the figure. If the pipeline fails immediately with an error like Error in library(ggplot2): there is no package called 'ggplot2', your lock file was never updated after you added the package. Run renv::snapshot() again and commit the updated file.
Step 7. Archive with a DOI and link it everywhere
GitHub repositories are movable and editable, which makes them poor citation targets. Archive a snapshot in a repository that issues a persistent identifier:
- Create a release on GitHub tagged
v1.0.0at the exact commit used for the manuscript. - Upload the release archive (or connect your GitHub account to Zenodo so releases are archived automatically) to Zenodo, OSF, Dryad, or a domain archive such as MetaboLights for metabolomics data or the database your field maintains.
- Choose a license. For code, MIT or BSD-3-Clause are permissive choices. For data, CC BY 4.0 is the common default.
- Record the DOI.
The Truth Effect Database illustrates what mature, FAIR-aligned packaging looks like at scale, combining user-friendly submission and retrieval tools with trial-level data harmonized for reuse in meta-analyses and reanalysis [15]. Your single-study package follows the same principles in miniature: findable through the DOI, accessible under a license, interoperable through standard formats, reusable through documentation.
The key options at each layer are summarized here.
| Layer | Lightweight option | More robust option | What it guarantees |
|---|---|---|---|
| Dependencies (R) | sessionInfo() report | renv.lock + renv::restore() | Exact package versions reinstall |
| Dependencies (Python) | pip freeze | Conda environment.yml | Pinned package stack |
| Execution | run_all.R driver script | Container image | Same behavior on any machine |
| Data sharing | Supplemental files | Domain repository with DOI | Persistent, citable, discoverable |
| Code citation | README link to GitHub | Zenodo release DOI | Frozen, versioned snapshot |
| Sensitive data | Reduced tier-1 dataset [13] | Deidentified analytic dataset with documented masking [12] | Auditable methods within privacy limits |
Step 8. Write the availability statement
The availability statement should name specific, resolvable locations, not promises. Compare:
Weak: "Data are available from the corresponding author on reasonable request."
Strong: "Analysis code is archived at https://doi.org/10.5281/zenodo.XXXXXXX (v1.0.0). The reduced analysis dataset supporting all reported endpoint results is available at the same DOI. Record-level raw data cannot be shared because of privacy constraints. The deidentification procedure and variable definitions are documented in the package."
The strong version is auditable. Availability statements that only promise materials are the reason deposited data could be located in fewer than two-thirds of cases in one audit of aging research articles [2].
A Reproducibility Checklist
Run every submission against this list before you send it out.
- Every reported number, table, and figure is produced by a script in the package.
- The pipeline runs end to end from a single entry point with one command.
- A fresh clone and environment restore were tested, and the outputs matched.
- Package and language versions are pinned in a lock file or requirements file.
- A session report is included in the docs folder.
- Raw data are deposited, or the highest supported tier of reduced data is deposited, with the restriction documented.
- A data dictionary defines every variable, unit, and allowed value.
- The README explains setup, run order, expected runtime, and expected outputs.
- A license covers both code and data.
- The archive snapshot carries a DOI, and the availability statement in the manuscript resolves to it.
Consensus work on reproducibility emphasizes that measures like these need institutional support to become routine, and that researchers consistently rank journal requirements and institutional incentives as the strongest levers for change [1]. Until those incentives fully arrive, the checklist is something you can control entirely yourself.
Common Mistakes and Limitations
Treating packaging as a final-stage task. Studies of reporting failures repeatedly find that methodological detail is lost when reporting is retrofitted at manuscript time rather than captured during the analysis [14]. Reconstructing which script made which figure six months later is the most expensive way to build a package. Capture continuously instead.
"Available on request" statements. These fail the reproducer and, as the audit of aging research showed, even stated availability often does not correspond to locatable materials [2]. Share actual files in actual archives.
Sharing code without pinned dependencies. Unpinned environments change under you. A package that runs today can break next year when a dependency updates its default behavior. Documenting versions and executable structure is precisely the gap identified in code-sharing assessments across clinical prediction research [3].
Hand-edited outputs. A figure touched up in design software, or a table with a value corrected directly in a spreadsheet, breaks the chain from data to result. Keep all transformations in code [10].
Absolute file paths. Paths like /Users/alice/Desktop/thesis/final_v3/ guarantee failure on anyone else's machine. Use paths relative to the project root, and never rely on your working directory happening to be set correctly.
Dumping an undocumented code folder. Researchers trying to reuse published work report that open code and metadata are frequently unavailable, incomplete, or unusable in practice [16]. The most commonly cited barrier is lack of time to prepare documentation, named by 65% of surveyed researchers, ahead of publication pressure at 51% [16]. The realistic fix is to document as you go and to scope the package honestly: a small, clean, tested package beats a sprawling dump of every script you ever wrote.
Ignoring license and privacy. A package without a license is legally all rights reserved, which means others cannot legally reuse it. And a package that leaks identifying information is worse than no package. Sensitive data demand the tiered approach described above, with deidentification and its effects quantified and documented [12].
Expecting perfection before starting. Full computational reproducibility is a high bar, and even under mandatory sharing policies with independent reproduction teams, robustness checks on real published research found that about 28% of significant results did not survive reanalysis in the same form [7]. That is the system working, not failing. Package at the level you can sustain, improve over time, and remember that expert reproducers themselves find lower robustness in the literature, which reflects their experience rather than unique flaws in your work [7].
Frequently Asked Questions
What does it mean to package code and data for reproducibility?
It means assembling the data, code, software environment, and documentation needed for another person to rerun your analysis and obtain your reported results, then archiving that bundle with a persistent identifier such as a DOI so it can be cited and located permanently.
What is the minimum viable reproducibility package?
A project folder with all analysis scripts, the analysis-ready data or a documented way to reconstruct it, a dependency lock file, a README explaining how to run the pipeline, and an archived snapshot with a DOI. That combination already supports independent verification of your results.
Which repository should I use for my code and data?
Use GitHub or a similar service for active development, then archive a frozen release to a repository that issues DOIs, such as Zenodo, OSF, or Dryad. For domain-specific data types, prefer field archives, for example MetaboLights or Metabolomics Workbench for metabolomics raw data, because they add domain metadata that generic repositories lack.
Do I need to use Docker or containers?
No. A pinned dependency environment plus a single driver script covers most needs and is far easier to maintain. Containers add value when system libraries, external binaries, or exact runtime behavior matter, such as for machine learning pipelines or analyses spanning multiple languages.
How do I write a good data and code availability statement?
Point to specific, resolvable DOIs or URLs for each component, state the version used, and explain any component that cannot be shared and why. Avoid vague phrases like available on request, because auditors have shown these often do not lead to locatable materials.
What if my data are confidential or contain patient information?
Share the highest tier the privacy rules allow. An analysis-ready reduced dataset plus complete code usually supports verification of your headline results, and a documented deidentification pipeline allows auditability without exposing raw records.
How do I cite my code in a paper?
Cite the archived release DOI in the availability statement and, where relevant, in the methods section. If the code depends on published methods or software packages, cite those packages by their own publications as well.
How much time does proper packaging take?
Preparation time is the barrier researchers cite most often, especially documentation, so build the habits into the analysis itself. A project organized from day one with version control, a lock file, and running scripts takes hours, not weeks, to package at submission time, while a retrofitted project can take days of archaeology.
Sources
- Prioritising measures and interventions to strengthen research reproducibility: a Delphi consultation study.
- An assessment of data and code sharing in research funded by the Nathan Shock Centers, 2017-2022: a meta-research study.
- AI-assisted scoping review of code sharing in clinical prediction model research.
- Extent of Open Science Practices in the Reporting of Real World Evidence Research.
- Journal research data policies in materials science.
- Funders' Expectations for Open Science in Cardiovascular Research: A Scoping Review of the Largest Cardiovascular Research Funders.
- Reproducibility and robustness of economics and political science research.
- Metabonaut: an open educational resource for learning reproducible, script-based untargeted LC-MS/MS metabolomics.
- eyeris: A Flexible, Extensible, and Reproducible Pupillometry Preprocessing Framework in R.
- tanggle: An R package for the visualization of phylogenetic networks.
- Paper mill or paper mine? A tentative answer to the sharp increase in research papers based on the Global Burden of Disease database.
- Balancing Privacy Protection and Reproducible Entity Extraction in Real-World Data in the Development of a Framework for Deidentified Japanese Electronic Health Record Narratives Using BERT: Retrospective Observational Study.
- Clinical trial data transparency should match data access to scientific purpose: a tiered framework for reproducibility and reuse.
- Transparent reporting is central to reproducible radiological AI research: A call to action.
- Introducing the Truth Effect Database (TED): An open trial-level resource promoting FAIR data in truth effect research.
- Exploratory Insights into Barriers and Open Practices for Computational Reproducibility in Scientific Research.