Skip the Custom CRUD App and Curate Your Data in GitHub Instead
Your team has a relatively small collection of data that a handful of people need to maintain. The data changes occasionally. Changes should be gated before they reach production. The content changes need to be validated, audited, deployed, and potentially rolled back.
Naturally, someone proposes building a CRUD application. Been there. That is the obvious solution.
My thinking: Don’t build that.
Instead, put the data in a Git repository.
Let contributors edit it through Git with developer / GitHub workflows and conventions. Use pull requests to propose changes. Run automated validation in GitHub Actions. Require approval before merging. Deploy the approved content through another GitHub Action to the production database.
Maybe this sounds radical to you: manage your data in Git, especially if the people maintaining the data are not creating software and writing code day-to-day. A custom application could provide a polished form, an editable table, or something that resembles Excel in a browser: the thing many of your users want.
That interface would almost certainly be easier to use. But it may also optimize the least important part of the system.
The Reality: You Are Not Building a Simple CRUD App
A basic CRUD application sounds easy. Create a page that lists the records or content. Add a form for creating, editing, and deleting them. Connect it to a database. Double-check your input validation. Add user authentication. Deploy it.
Done.
Except the data should not change immediately in production when someone clicks Save. The change should exist as a proposal. Someone else should review it. Automated checks should validate it for consistency. Only approved changes should be deployed. The system should retain a complete history of what changed, who changed it, and why.
Now the application needs:
- Draft and published states
- Approval workflows
- Role-based permissions
- Comments for feedback
- Change history
- Human-readable diffs
- Automated validation
- Deployment automation
- Rollback
- Audit logs
At this point, you are no longer building a simple CRUD application. You are building a specialized content management system that shares a lot of characteristics with a source control and release management platform.
You can build all of that. The question is whether you should.
Most teams building an internal data management application will focus on the part their internal users can see. The part the user is asking for. They will polish the table, form, filters, search, and editing experience. Make sure the colors, font, and spacing are all just right. The workflow around the edit will receive less attention, if any.
Using GitHub like I’m suggesting is effectively inverting all of those tradeoffs. Its editing experience is generic, and admittedly not as beginner-friendly, but its change management model is mature. A familiar custom interface can conceal a weak workflow. An unfamiliar GitHub interface can expose a much stronger one.
The proposal is not to make your production application read directly from a Git repository. Git is the governed source of truth.
The repository contains the version that people author, review, and approve. A deployment pipeline validates and publishes that content into the systems that actually consume it.
The destination might be a relational database, document store, object store, search index, vector database, static website, or several of those destinations in combination. That part is up to you and your specific use case.
This loosely decouples the authoring format and workflows from the production runtime components.
Humans can maintain readable Markdown, YAML, JSON, or CSV files. A pipeline can validate them, combine them, normalize them, and generate whatever representation needs to be loaded idempotently into the production system.
The pipeline produces and deploys the copy used by the real production systems.
The Compromise: Editing Experience Is Worse
GitHub is not a purpose-built data editor.
A custom application could provide fields with labels, dropdowns, autocomplete, rich previews, and carefully designed error messages. GitHub exposes concepts such as files, branches, pull requests, checks, and merges. We aren’t even in the same neighborhood when it comes to a polished user experience.
My argument is that this aspect of the user experience matters less… in some circumstances.
Those concepts will be unfamiliar to many business or domain users. That does not automatically make the workflow unreasonable.
The users do not need to install Git, configure SSH keys, or work from a terminal. Maybe some will, and that is fine. But for a simple Markdown or CSV file management workflow, they can edit a file on the GitHub.com site in their browser, create a branch, open a pull request, respond to feedback, and merge the approved change.
Conceptually, the workflow is:
That is more complicated than clicking ‘Save’. It is also a more accurate representation of what we want to happen.
The change does not immediately mutate production data. It is a proposal moving through a gated release process with both technical and human checks required. Multiple changes may be pending at the same time. Changes may be rejected or require multiple iterations.
There is a difference between an experience being unfamiliar and an experience being unusable.
Organizations routinely train employees to use specialized internal systems. GitHub simply exposes more of the underlying process than a custom form would.
The argument is not that GitHub provides a better editing experience. It does not. It is that a slightly better editing experience may not justify building and supporting an entire custom workflow with approval, validation, auditing, deployment, and rollback capabilities.
The Tradeoffs: Where This Approach Works
This is not a replacement for all CRUD applications. It works for a specific class of problems. Use the following as criteria for whether you should use this approach.
1. A Small Number of Contributors
The strongest fit is a dataset maintained by a relatively small group of people.
Get Jared Hatfield’s stories in your inbox
Join Medium for free to get updates from this writer.
There may be many consumers of the data, but the number of people proposing changes should be limited enough that reviews and potential merge conflicts remain manageable. Git can scale to many contributors, but for this type of use case more contributors mean more complexity.
2. Modest Change Velocity
The data should change slowly enough that each change can be treated as a proposal handled in the time scale of days.
This is not a model for transactional data, continuous events, or hundreds of simultaneous updates. For time-sensitive changes requiring many updates in minutes, this is the wrong path.
Git is good at managing deliberate changes to a corpus.
It is not a replacement for a real-time transactional database.
3. Governed Releases
The approach becomes much more compelling when changes should be reviewed, validated, and approved before they reach production.
If any authorized user must be able to update the data immediately, GitHub may introduce unnecessary ceremony, but that does not necessarily disqualify this approach, as GitHub Actions can still apply programmatic checks.
If changes require governance, adopting this approach means adopting the ceremonies of pull requests, approvers, and automated checks, not reinventing them.
4. Manageable Data Size
The dataset must fit comfortably into a Git repository. This can be disqualifying for many use cases.
Kilobytes, megabytes, and tens of megabytes are easily managed in a single repository. Hundreds of megabytes may be possible but deserve scrutiny. Gigabytes of frequently changing content are a clear sign that this is the wrong architecture.
The same applies to file counts. Tens, hundreds, thousands, and even tens of thousands of files may be manageable. Hundreds of thousands or millions of files within a single Git repository definitely are not.
The question is not whether Git can technically store the data.
The question is whether people can browse, edit, review, validate, and deploy it without the repository becoming a burden.
Unstructured Content Is the Easiest Fit
Markdown is the clearest example.
GitHub already provides a browser-based editor, rendered previews, line-level diffs, comments, and pull request reviews.
Potential use cases include documentation, operational procedures, notification text, policy content, string translations, knowledge bases, and content used by retrieval systems.
The deployment pipeline can publish the same content to multiple destinations. Markdown files could be copied to object storage, rendered into a static website, indexed for search, or processed into a vector database.
The repository remains the governed source while the generated outputs are what people and applications consume.
Structured Data Works As Well
Structured content introduces some additional challenges, but the use case is still compelling.
YAML, JSON, and CSV can work well for slowly changing configuration, lookup tables, group membership, artifact manifests, controlled feature flags, and other datasets.
The key requirement is validation.
On each pull request, a GitHub Actions workflow can catch syntax errors, missing required fields, invalid values, duplicate identifiers, broken references, and business rule violations before anything is merged. Data quality is a first-class citizen here, built into the pipeline.
A validator can also run locally for contributors who want faster feedback through scripts or custom applications, but the pipeline remains authoritative.
One benefit of structured data is that the source files do not need to match the deployed format. Store the files in whatever format is most convenient for the maintainers. A compiler or export process step can combine files, resolve references, apply defaults, normalize values, and generate the actual records to upsert into a database or deploy to another system.
This allows the repository to remain optimized for human maintenance and review while the output is optimized for machines.
Automated checks answer, “Is this change valid and able to be deployed?”
Human reviewers answer, “Is this change correct and desirable based on our requirements?”
Both are necessary.
But Can’t I Just Vibe Code the CRUD App?
Agentic software development has fundamentally changed the cost of creating niche software tools. It is easier than ever before to create custom applications with a simple prompt.
That reduces the initial cost of creating a custom interface. It does not eliminate the surrounding complexity.
The application still needs security, testing, deployment, monitoring, maintenance, permissions, approval workflows, history, validation, rollback, and operational support.
More importantly, generating an interface does not automatically produce a mature change management model.
Vibe coding may make the form cheap.
It does not make the workflow robust and trustworthy. The approach proposed here is about the workflow as much as it is about the technology.
The Question: Ask What You Are Actually Building
Suppose the real requirement is this:
A small group of people maintains a modest corpus of structured or unstructured data. Changes happen occasionally. Each change should be reviewed, validated, approved, audited, deployed, and reversible.
That is not primarily a data entry problem.
It is a change management problem.
GitHub already provides a mature model for that. It preserves history, shows the diff, supports discussion and approval, runs automated checks, protects the release branch, and can trigger deployment.
The editing experience will not be perfect. That may be fine.
For a small, slow-moving, governed dataset, a less polished editing experience may be a better tradeoff than building and maintaining a custom application just to recreate versioning, approval, validation, deployment, and rollback.
This approach is not right for every CRUD application. Most of the time, it will not be.
But before building another internal editor, ask what problem you are actually solving.
You may not need another application.
You may already be using the platform that has the workflow you need.









