
Building an Enterprise ERP from Scratch
Introduction
When I joined Integral Progress Technology, I expected to build user interfaces and implement features.
What I didn't expect was how much I would learn about software architecture, reusable systems, performance, and building software that hundreds of users could rely on every day.
Over the next two and a half years, I worked on a modern ERP platform built with React, Laravel, and Inertia.js. As the project evolved, so did my responsibilities. I went from implementing features to designing reusable components, making architectural decisions, and eventually leading the front-end development of the application.
This article isn't about the technologies I used. It's about the engineering challenges that changed how I think about software.
The Challenge of Building an ERP
Unlike a typical CRUD application, an ERP quickly becomes a collection of dozens of interconnected systems.
Every feature has business rules.
Every screen depends on another.
Every optimization affects multiple teams.
It doesn't take long before copying components or writing quick fixes becomes impossible. Everything needs to be designed for long-term maintenance.
That realization changed how I approached development.
Moving Beyond Pages
One of the biggest shifts in my career was realizing that building pages isn't the difficult part.
Building systems is.
Instead of creating individual screens, I started designing reusable building blocks that could power multiple modules across the application.
Over time I worked on components such as:
A reusable data table
A Kanban board
File management components
A reusable comments system
Dynamic forms
Shared layouts and UI primitives
Every component had to be flexible enough to support different business requirements while remaining simple for other developers to use.
The goal was never to solve one problem.
The goal was to solve the same problem once.
Designing a Truly Reusable Table
One of the most challenging pieces of the ERP was the table component.
At first glance, tables seem straightforward.
Display data.
Add pagination.
Maybe add sorting.
In reality, enterprise applications expect much more.
The table eventually needed to support:
Server-side pagination
Client-side and server-side sorting
Searching
Advanced filtering
Bulk actions
Row actions
Custom cell rendering
Dynamic columns
Loading states
Permission-aware actions
Reusability across dozens of modules
The biggest challenge wasn't writing the component.
It was designing an API that remained intuitive while supporting all those use cases without becoming difficult to maintain.
That experience taught me that API design is just as important as writing implementation code.
Balancing Flexibility and Simplicity
One mistake I made early on was trying to make components capable of solving every possible future problem.
Eventually I learned that flexibility has a cost.
Every additional prop.
Every optional behavior.
Every configuration.
All of them increase complexity.
Finding the balance between abstraction and simplicity became one of the most valuable lessons of my career.
Today I prefer solving real problems over hypothetical ones.
Performance Matters More Than Features
As more modules were added to the ERP, performance became increasingly important.
Large datasets.
Complex tables.
Rich forms.
Nested components.
Every unnecessary render became noticeable.
Instead of immediately reaching for optimization techniques, I learned to measure first.
Many improvements came from simplifying component hierarchies, reducing unnecessary state updates, improving rendering behavior, and designing components with performance in mind from the beginning rather than treating optimization as an afterthought.
Building for Other Developers
One responsibility I particularly enjoyed was creating components that other developers would use every day.
That changed the way I wrote code.
Instead of asking,
"Does this work?"
I started asking,
"Will another developer understand this six months from now?"
Good documentation.
Predictable APIs.
Consistent naming.
Helpful defaults.
Clear error handling.
These became just as important as functionality.
Developer experience is a product too.
Working Across the Stack
Although my primary responsibility was front-end development, working closely with Laravel and Inertia.js helped me better understand how frontend and backend systems should communicate.
Many challenges weren't frontend problems or backend problems.
They were contract problems.
Improving communication between both sides often solved issues faster than writing more code.
This experience reinforced the importance of collaboration and designing interfaces—not only for users, but also between systems.
Taking Ownership
Perhaps the biggest change wasn't technical.
It was learning to take ownership.
Instead of simply completing assigned tasks, I found myself asking questions like:
Can this component be reused elsewhere?
Can this API be simplified?
Will this solution still make sense in a year?
Should we refactor this before adding another feature?
Taking ownership meant thinking beyond the current ticket and considering the long-term health of the codebase.
Becoming a Front-End Lead
As my responsibilities grew, I transitioned into leading the front-end development of the ERP.
The role became less about writing the most code and more about enabling the rest of the team.
That included:
Defining reusable patterns
Reviewing pull requests
Maintaining consistency
Making architectural decisions
Helping teammates solve difficult problems
Improving code quality across the project
I learned that leadership isn't about making every decision.
It's about creating an environment where good decisions become easier.
Lessons I'll Carry Forward
Looking back, the most valuable thing I built wasn't a table component, a Kanban board, or a file manager.
It was the mindset that software engineering is about solving problems thoughtfully rather than writing the most code.
Some of the lessons I'll continue carrying into future projects are:
Build systems instead of isolated features.
Simplicity usually scales better than cleverness.
Great APIs are invisible.
Performance should be designed, not patched.
Code is written once but read hundreds of times.
Good communication is an engineering skill.
Taking ownership creates opportunities for growth.
Final Thoughts
My time at Integral Progress Technology transformed the way I think about software engineering.
I joined expecting to build interfaces.
I left having learned how to design maintainable systems, balance flexibility with simplicity, collaborate across teams, and build software intended to evolve for years.
Those experiences continue to shape every project I work on today, and they have given me a stronger appreciation for building software that is not only functional, but also maintainable, scalable, and enjoyable for other developers to work with.
