The dream of the solo developer shipping a world-class product from a laptop is under pressure. A recent piece making the rounds on Hacker News (at https://lectronz.com/u/lectronz/articles/how-europe-is-killing-makers-and-micro-entrepreneurs) argued that a wave of European regulations like the Digital Services Act (DSA), DAC7, and GDPR is making it impossible for small makers to survive. The compliance burden, the author says, is just too high.
They're not wrong about the burden. It's real. Where we disagree is the conclusion. These regulations aren't killing small businesses. They're killing a specific way of building software: the simple, monolithic web app that treats the entire world as a single jurisdiction. The real story here isn't about legal red tape. It's about brittle architecture. The era of bolting on compliance as an afterthought is over. If you're building software today, you need to treat compliance as a core architectural concern from day one.
At AgileStack, we've seen this firsthand. Teams that treat GDPR or sales tax as a 'last-mile' problem end up in a world of pain. They get stuck in refactoring hell, trying to disentangle user data from a single database or jam region-specific logic into a controller that was never designed for it. The teams that succeed are the ones who see this for what it is: an engineering problem that demands a robust, decoupled solution.
The Monolith Can't Handle Reality Anymore
Think about the classic SaaS starter project. Maybe it's a Rails, Django, or Node.js app. You have a user model, a subscription model, and you hook it up to Stripe. For a decade, that was enough to get you started. You could reach a global audience with a few days of work.
Now, let's map the new reality onto that simple architecture.
VAT MOSS: A customer signs up from Germany. You now need to identify their location, calculate the correct Value Added Tax (19% for Germany), collect it, and remit it to the German government via the EU's One-Stop Shop. Your simple
price_in_centscolumn in theplanstable just became obsolete. You now need a dynamic pricing engine that's location-aware. Where does that logic live? In your controller? In the model? It gets messy fast.GDPR: That German customer invokes their right to be forgotten. You can't just run
DELETE FROM users WHERE id = ?. What about the logs that contain their email address? What about the data in your transactional email provider (like MailStack)? Or your analytics platform? A simple delete operation has now become a complex, distributed transaction across multiple systems, all of which need to be audited.Digital Services Act (DSA): If you allow user-generated content, you now have new obligations for content moderation and transparency. This means you need systems to track reports, actions taken, and notify users. This isn't just business logic. It's a formal, auditable process that your software must enforce. Your
poststable with a simpleis_hiddenboolean flag is no longer sufficient.
When you try to shoehorn these requirements into a classic monolith, you end up with a mess of if (user.is_eu) statements scattered across your codebase. Your business logic becomes hopelessly tangled with compliance logic. It's unmaintainable, untestable, and a huge drag on your team's velocity. This isn't a legal problem. It's a code smell.
Your Stack Needs a Compliance Abstraction Layer
The solution is to stop thinking about compliance as a feature and start thinking about it as a cross-cutting concern, like logging or authentication. You need to build an abstraction layer for it. A set of services and interfaces that isolate compliance logic from the core functionality of your application.
What does this 'compliance layer' actually do? It becomes a central clearinghouse for any operation that has regulatory implications.
Key Components of a Compliance Layer
- Policy Engine: This is the brain. It's a service that can answer questions like, "What's the tax rate for a customer in Portugal?" or "What's the data retention policy for an inactive user in California?" This could be a simple internal microservice or a sophisticated system using a rules engine like Open Policy Agent (OPA).
- Identity & Location Service: You can't apply policy without knowing who and where your user is. This service is responsible for securely storing user identity and reliably determining their geographic location at the time of a transaction. It abstracts away the complexity of GeoIP lookups, address verification, and identity proofs.
- Data Residency Manager: This component knows where data is allowed to live. When your application needs to save user data, it doesn't talk directly to a database. It asks the Data Residency Manager, "Store this PII for EU user 123." The manager then routes the data to the correct physical location, maybe a Postgres instance running in
eu-central-1. - Audit Log: Every action taken by the compliance layer must be recorded in an immutable log. When a user's data is deleted for a GDPR request, the log should record who made the request, when it was fulfilled, and which systems were affected. This isn't your standard application log. It's a permanent, verifiable record for regulators.
Building this doesn't mean you have to write everything from scratch. It's about choosing the right tools and composing them intelligently. Use a Merchant of Record like Paddle or Lemon Squeezy to completely outsource VAT MOSS. Use a dedicated service for consent management. Your job is to architect the glue that connects these services to your core application in a clean, decoupled way.
Refactoring for Compliance: A Practical Example
Let's make this concrete. Imagine we have a simple note-taking SaaS built with Node.js and Express. The 'old way' might look like this.
// The old, brittle way
app.post('/notes', async (req, res) => {
const { userId, content } = req.body;
// Is the user in the EU? Check their profile maybe?
// This gets messy fast. What if their profile is out of date?
const user = await db.users.find(userId);
if (user.country === 'DE') {
// Special logging for EU? Encrypt differently?
// Compliance logic is tangled with business logic.
}
const note = await db.notes.create({ userId, content });
res.json(note);
});
This is a maintenance nightmare. Every developer who touches this endpoint needs to be a compliance expert.
Now, let's refactor this to use a compliance layer. We'll introduce the concept of a complianceService that our application can call.
// Pseudocode: A better, decoupled way
// 1. A compliance middleware runs first
app.use(async (req, res, next) => {
const userRegion = await locationService.getRegion(req.ip);
const policy = await policyEngine.getPolicyForRequest(req.user, userRegion);
req.compliancePolicy = policy; // Attach policy to the request object
next();
});
// 2. The data storage logic is abstracted
class NoteRepository {
constructor(db, auditLog) {
this.db = db;
this.auditLog = auditLog;
}
async create(note, policy) {
// Use the policy to determine WHERE to store the data
const databaseConnection = this.db.getConnectionForRegion(policy.dataResidency);
const newNote = await databaseConnection.notes.create(note);
// Log the action to an immutable audit trail
await this.auditLog.log('NOTE_CREATED', {
noteId: newNote.id,
userId: note.userId,
region: policy.dataResidency
});
return newNote;
}
}
// 3. The controller is clean and simple again
const noteRepository = new NoteRepository(db, auditLog);
app.post('/notes', async (req, res) => {
const { userId, content } = req.body;
// The controller doesn't know or care about compliance rules.
// It just passes the policy object to the data layer.
const note = await noteRepository.create({ userId, content }, req.compliancePolicy);
res.json(note);
});
Look at the difference. The Express route handler is back to doing one thing: handling HTTP requests. The complex logic about data residency and auditing is neatly encapsulated in the NoteRepository and the middleware. We can now change our data residency rules by updating the policyEngine without ever touching the application's core business logic. This is a resilient, scalable architecture.
This Is the Future of Global Software
It's tempting to view this as a 'Europe problem'. It's not. California has the CCPA and CPRA. Canada has PIPEDA. Brazil has the LGPD. The global trend is unambiguous: governments are enforcing digital sovereignty and user rights. The internet is no longer a lawless frontier. It's being balkanized into regulatory zones, and your software must be able to navigate them.
Building a compliance-first architecture isn't just about avoiding fines. It's a massive competitive advantage. When a new market introduces a data residency law, a team with a compliance layer can adapt in days. They update their policy engine, spin up a new database in the required region, and deploy. A team with a tangled monolith faces months of painful, risky refactoring. Who do you think will win?
This is a huge opportunity for developers, architects, and companies like us. The demand for tools and consulting (like our work at AgileStack and our products like ESig and MailStack) that simplify this complexity is exploding. Building these systems is the new frontier of web development.
What This Means for Your Team
- Stop treating compliance as a legal problem. It's an architecture problem. Get your engineers and architects involved from the very beginning. They're the ones who have to build it.
- Isolate compliance logic. Never let policy logic bleed into your core business logic. Use middleware, dedicated services, or an event-driven architecture to keep them separate.
- Outsource aggressively. Don't build your own global tax collection system. Use a Merchant of Record like Paddle, Stripe Tax, or Quaderno. Their entire business is solving this one problem.
- Design for data locality from day one. Even if you only deploy in
us-east-1today, design your data layer as if it might need to run in multiple regions tomorrow. Tag data with its origin and policy requirements. - Log for the audit. Your standard application logs are not enough. You need a separate, immutable audit log that tracks every compliance-related event. When the regulators come knocking, this will be your best friend.
The friction for solo developers is real, but the answer isn't to wish the regulations away. The answer is to build better, more disciplined software. The internet is growing up, and our architectures need to grow up with it.
Building something in this space? AgileStack helps teams ship enterprise-grade software without the consulting-firm overhead. Book a 30-minute call and tell us what you're working on.