Case Study 2: From Student Project to Open Source
How to take PennyWise public, attract contributors, manage issues, and build a community around your Pascal project.
Background
Rosa has been using PennyWise 2.0 for three months. Her accountant loves the CSV reports. Her freelancer friends keep asking, "Can I get a copy of that program?" Tomas has been sharing his version with classmates, and two of them have already asked if they can add features — one wants multi-currency support, another wants a dark mode.
Rosa and Tomas have the same realization simultaneously: PennyWise should be open source.
This case study walks through the process of taking a student project and turning it into a real open-source project. The technical skills are ones you already have. The new skills are social, organizational, and communicative — and they are just as important as the code.
Step 1: Preparing the Code for Public Release
Before anyone else sees your code, you need to do three things: clean it, document it, and license it.
Code Cleanup
Rosa goes through the codebase and finds:
- Hardcoded paths. A database path that points to C:\Users\Rosa\Documents\PennyWise\data.db. This works on her machine and nowhere else. She replaces it with GetAppConfigDir(False) + 'pennywise.db', which uses the operating system's standard configuration directory on every platform.
- Debug WriteLn statements. Seventeen WriteLn('DEBUG: ...') statements scattered through the code, left over from late-night debugging sessions. She removes them all.
- Commented-out code. Three procedures that were superseded by better implementations but never deleted. She deletes them — Git preserves history, so nothing is truly lost.
- Inconsistent naming. Some variables use camelCase, others use PascalCase, and two use snake_case. She standardizes on Pascal's conventional PascalCase for types and methods, APrefixed for parameters, and FPrefixed for private fields — the style used throughout this textbook.
Documentation
Tomas writes four documents:
- README.md — Project description, screenshots, build instructions, contributing guidelines, and license notice.
- INSTALL.md — Step-by-step installation for Windows, Linux, and macOS, including Free Pascal and Lazarus installation links.
- CONTRIBUTING.md — How to report bugs, suggest features, and submit code changes.
- LICENSE — The license text (they choose the MIT License — see below).
Choosing a License
This is the most important non-technical decision. Without a license, the code is "all rights reserved" by default — no one can legally use, modify, or distribute it. Rosa and Tomas research three common options:
| License | Permissions | Conditions | Good For |
|---|---|---|---|
| MIT | Use, modify, distribute, commercial use | Must include license text | Maximum adoption |
| GPL v3 | Use, modify, distribute | Derivative works must also be GPL | Ensuring code stays open |
| LGPL | Use, modify, distribute | Libraries can be used in proprietary code; modifications to the library itself must be open | Open-source libraries |
They choose the MIT License because their goal is maximum adoption. They want people to use PennyWise, learn from it, modify it, and even include it in commercial products. The MIT License allows all of this with only one condition: the license text must be included in any distribution.
The Free Pascal compiler is licensed under the LGPL (with a static linking exception), and the Lazarus IDE is licensed under the GPL. PennyWise's own code, however, can be MIT-licensed because it is an independent application that uses these tools, not a derivative work of them. (This is a common source of confusion — using a GPL-licensed compiler does not make your compiled program GPL.)
Step 2: Setting Up the Repository
Rosa creates a repository on GitHub (other options include GitLab, Codeberg, and SourceHut — all support Pascal projects).
Repository Structure
PennyWise/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ └── build.yml
├── src/
│ ├── PennyWise2.lpr
│ ├── PennyWise2.lpi
│ ├── FinanceCore.pas
│ ├── FinanceDB.pas
│ ├── FinanceUI.pas
│ ├── FinanceExport.pas
│ └── FinanceSync.pas
├── tests/
│ ├── TestFinanceCore.pas
│ └── TestRunner.lpr
├── docs/
│ ├── INSTALL.md
│ ├── USER-GUIDE.md
│ └── screenshots/
├── .gitignore
├── README.md
├── CONTRIBUTING.md
├── LICENSE
└── CHANGELOG.md
The .gitignore File
# Compiled binaries
*.exe
*.dll
*.so
*.dylib
# Free Pascal object files
*.o
*.ppu
*.compiled
*.or
*.res
# Lazarus session files
*.lps
# Backup files
*.bak
*~
# Database files (user data, not source)
*.db
*.db-journal
# IDE project directories
lib/
backup/
Issue Templates
The bug report template guides users to provide the information developers need:
## Bug Report
**PennyWise version:** [e.g., 2.0.1]
**Operating system:** [e.g., Windows 10, Ubuntu 24.04, macOS Sonoma]
**Free Pascal version:** [e.g., 3.2.2]
**Description:**
A clear description of the bug.
**Steps to reproduce:**
1. Open PennyWise
2. Click ...
3. ...
**Expected behavior:**
What should happen.
**Actual behavior:**
What actually happens.
**Screenshots:**
If applicable, add screenshots.
Step 3: Attracting Contributors
The hardest part of open source is not writing code — it is building a community. Rosa and Tomas use several strategies:
Good First Issues
They label simple, well-defined tasks as "good first issue" — the standard label that tells newcomers, "This is a safe place to start." Examples:
- "Add a 'dark mode' color scheme" (modify form colors, no business logic changes)
- "Improve date format parsing to handle DD/MM/YYYY" (a focused bug fix in
TCSVImporter.ParseDate) - "Add a keyboard shortcut for 'Add Transaction'" (a one-line change in the form designer)
- "Translate the UI to Spanish" (add string resources, no code changes)
Each issue includes a description of the problem, a sketch of the solution, and pointers to the relevant source files. The goal is to make contributing easy — the contributor should spend their time coding, not figuring out where the code lives.
Code Review
When a contributor submits a pull request, Rosa and Tomas review it together. They follow a code review checklist:
- Does it compile? (The CI pipeline checks this automatically.)
- Does it pass existing tests? (Also checked automatically.)
- Does it include new tests for new functionality?
- Does it follow the project's coding style? (PascalCase, F-prefixed fields, etc.)
- Is the commit message descriptive?
- Does the change do one thing? (A pull request that adds dark mode AND fixes a CSV bug should be split into two.)
Community Communication
They set up: - A Discussions tab on GitHub for questions and feature brainstorming. - A CHANGELOG.md that tracks what changes in each release, so users know what to expect. - A releases page with compiled binaries for each platform, so users who cannot compile from source can still use PennyWise.
Step 4: Managing Releases
Tomas learns about semantic versioning (SemVer): MAJOR.MINOR.PATCH.
- PATCH (2.0.0 to 2.0.1): Bug fixes only. No new features, no breaking changes.
- MINOR (2.0.1 to 2.1.0): New features that do not break existing functionality.
- MAJOR (2.1.0 to 3.0.0): Breaking changes (e.g., database schema change that requires migration).
Their first release is v2.0.0. A week later, they fix three bugs and release v2.0.1. A month later, a contributor adds multi-currency support and they release v2.1.0.
Each release includes: - Compiled binaries for Windows (64-bit), Linux (64-bit), and macOS (arm64). - A changelog entry listing all changes since the previous release. - SHA-256 checksums for each binary so users can verify the download was not tampered with.
Step 5: Real-World Results
Six months after going public, PennyWise has: - 47 stars on GitHub. Modest, but each star represents someone who found value in the project. - 12 contributors who have submitted code. Five are students who used PennyWise as a learning project. Three are experienced Delphi developers who found PennyWise through the Free Pascal forums. Four are people who use PennyWise to manage their own finances and fixed bugs that annoyed them. - 23 closed issues and 8 open ones. The open issues include feature requests (receipt scanning, budget graphs by week) and a known bug on macOS Monterey. - 3 forks where developers have customized PennyWise for their own needs: one for a small business (adding invoicing), one for a church (tracking tithes and donations), and one for a student organization (tracking club dues).
These numbers are small by the standards of major open-source projects. But they are not small by the standards of the Pascal community, where a project with a dozen active contributors is significant. And they represent something that no amount of code quality can measure: other people using your software, finding value in it, and contributing back to it.
Lessons Learned
-
Documentation is the first feature. The README is the most important file in the repository. If a potential contributor cannot understand what the project does and how to build it in five minutes, they leave.
-
Make contributing easy. "Good first issue" labels, clear CONTRIBUTING.md, and a CI pipeline that catches basic errors before code review — these reduce the friction for newcomers from hours to minutes.
-
Code review is a teaching opportunity. When Rosa reviews a contributor's code and suggests a more idiomatic approach, both people learn. The contributor learns Pascal style; Rosa learns to articulate what she knows.
-
Open source is a conversation. It is not "I build, you use." It is "We build together." Issues are questions. Pull requests are proposals. Releases are answers. The best open-source projects are the ones where the maintainers listen.
-
Pascal projects have an audience. The Pascal community is smaller than Python's or JavaScript's, but it is active, knowledgeable, and welcoming. A well-maintained Pascal project will find its users — and some of them will become contributors.
Rosa's PennyWise started as a homework assignment in Chapter 1. It is now a real piece of software used by real people. That is the arc of this entire textbook, compressed into a single project.