111

I'm a web developer of a small, local SaaS web application. It currently has about a half-dozen clients.

As I continue to design the application, it's become increasingly harder for me to convince myself to commit any time to the project, which has happened in the beginning phase. Having grown attached to the project and the code I've already written, I'm scared that all additional work I commit will be overturned in the near future, when the app turns out to not scale well as the business grows.

As a university student applying for internships, I've had employers question my choice in not using any web frameworks during interviews, which has only caused me to further doubt my previous work. I simply don't know any web frameworks, and don't know which one to start using.

I've landed an internship as a full-stack developer in January, where I'll begin to learn front-end frameworks, but the pressure to finish the app is mounting, and I'm considering scrapping the app completely and starting over, which is something I've done before. The app currently is built in PHP and jQuery (for AJAX calls) and uses MySQL for its database. Any thoughts on how I can overcome this mental block, and to ensure my app will be scalable? Thanks in advance.

cameraguy258
  • 1,229

9 Answers9

203

Perfect is the enemy of good.

Or put another way, don't worry about it today. If your app does what it needs to do, then it's fine. It's not a bad thing to rewrite parts of software further down the line; by that point you 1) know more clearly what you're trying to build and 2) know which bits are actually the bottleneck. You could spend an enormous amount of time writing an app which would scale to a million users, but it wouldn't be any better for your current six customers than what you've got today.

Laiv
  • 14,990
112

Any thoughts on how I can overcome this mental block, and to ensure my app will be scalable?

The crux of the issue isn't scalability. The crux of the issue is thinking that you will get it right the first time.

You should focus on writing clean code. Because clean code maximizes convenience when you (inevitably) have to change something in the future. And that's the real goal you should have.

What you're trying to do now is try to think of the perfect code to write. But even if you manage to do that, who says the requirements aren't going to change, or you maybe made your decisions based on wrong information or miscommunication?

You cannot avoid making mistakes, even if they're not your fault. Focus on writing code in which it's easy to change things later, instead of hoping to write code that you won't need to change in the future.

Having grown attached to the project and the code I've already written,

I absolutely sympathize with this sentiment. But getting attached to the code you've written is a problem.

The only thing that should be a constant is your desire to solve a specific problem. How you go about solving that problem is only a secondary concern.

If tomorrow a new tool is released that reduces your codebase by 80%, are you going to be upset that your code is no longer used; or are you going to be happy that your codebase has become smaller and much cleaner/more manageable?

If the former, you have a problem: you're not seeing the solution for the code. In other words, you're focusing on the code and not seeing the bigger picture (the solution it aims to provide).

I'm scared that all additional work I commit will be overturned in the near future, when the app turns out to not scale well as the business grows.

That is a different problem for a different day.

First, you build something that works. Secondly, you improve the code to fix any flaws it may still show. What you're currently doing is holding back on the first task out of fear of then having to do the second task.

But what other option is there? You cannot tell the future. If you spend your time pondering future possibilities, you're going to end up guessing anyway. A guess is always prone to being dead wrong.

Instead, build the application, and prove that there is indeed an issue. And once the issue is clear, then you start addressing it.

To put it another way: Henry Ford never built a car that conforms to 2018 standards/expectations. But if he hadn't built the Model T, a flawed car by modern standards, no one would have started using cars, there would be no car industry, and no one would have had a car that they could then try to improve.

I've had employers question my choice in not using any web frameworks during interviews, which has only caused me to further doubt my previous work.

The important part here is not which framework you're using (any employer who judges you on that is not doing their job properly). The important part here is knowing what you're doing and why you're doing it.

For example, you could be avoiding existing framework specifically because you want to learn why a framework is useful by doing it the hard way first. Or you could be trying to make your own framework.

The only bad answer here is "I don't know", as it shows a lack of making informed decisions. That is a red flag for an employer.

I simply don't know any web frameworks, and don't know which one to start using.

The same problem arises here. The solution is not to think more, but rather to act:

  • Stop pondering the perfect answer.
  • Pick a framework. Unless you have a preference, pick a random one. Use a dartboard, roll a die, flip a coin, pick a card.
  • Use it.
  • Did you like using it? Was there anything you found annoying?
  • Look up how to prevent these bad elements. Did you misuse the framework, or is this just how the framework is supposed to work?
  • Once you feel you have a grip on the framework (regardless of whether you like it or not), pick a new framework and repeat the cycle.

To read more on this, read The doing mindset > the thinking mindset. The author explains it better than I can.

but the pressure to finish the app is mounting, and I'm considering scrapping the app completely and starting over

Unless the current codebase is an absolutely unmaintainable mess; you're making the opposite decision.
Developers often think that throwing things out would be the better choice. It's a very common feeling. But it is rarely the right choice.

Throwing code out and starting from scratch is like getting stuck in traffic on your way to work, worrying you'll be late to work (miss the deadline), and instead drive home and try driving down the same road again. It doesn't make sense. You may be stuck in traffic, but you're still closer to work than you were when you were at home.

Flater
  • 58,824
18

Despite the enormous amount of money Facebook and Google have poured into marketing to convince you otherwise, front end frameworks exist for two primary reasons:

  • First, offloading hardware/network demands to client-side operations by way of putting state and logic in the client
  • Second, pertinent to the additional client logic necessary to support the first point, they provide isolated execution contexts so that you can cram other people's code into a page without breaking anything.

You probably only need to reach for a framework to solve these problems if your application is inherently stateful, if the amount of application state you're saving client side is quite complex, if you expect a great many clients with bad network latency (mobile, or distant from server), or if there is a strong business need to support particularly advanced CSS or dynamic element creation.

Framework marketing wants you to believe that their special method of architecture increases development velocity and makes maintenance easier. This is patently untrue for small teams working on simple projects. Isolating code and organizing imports may help a large team bring a product to market more quickly. It provides much less for a single person development team working on an already functional project.

You will spend more time learning how to fit existing, functional code into the framework than you will actually implementing features, and chances are pretty good that someone somewhere will update something, and code written in that framework will cease to function inside of 18 months unless someone is there to constantly maintain it it.

Vanilla JS, and to a lesser but still significant extent JQuery, do not suffer from those problems. With some notable exceptions, JQuery + AJAX applications not relying on browser specific behaviors, and forgoing external dependencies where sensible, continue to work 10-15 years after they were originally written with very minor changes.

Frameworks are great for typical startups supporting ongoing, complex, publicly facing web applications. They let large teams co-ordinate well together, integrate nicely with vendor add frameworks, and support flashy new widgets and design paradigms to help you stay competitive.

None of that matters for a small software tool with a fixed audience that you're about to abandon. Taking on a framework both slows your development velocity as you adapt to a new paradigm, and introduces unnecessary compatibility risks. Keeping client side code simple, (and ideally self hosted) means that the surface area of compatibility risk drops significantly. Browsers will change, CDN urls will stop working, dependencies will go out of date - But nobody is touching that server, and it will keep working just fine.

Don't adopt a framework unless it solves a specific architectural problem you have today or can foresee soon, and strongly consider addressing that concern by another means instead if that is at all tenable.

Nicol Bolas
  • 12,043
  • 4
  • 39
  • 48
Iron Gremlin
  • 1,115
  • 6
  • 8
7

The best thing you can do to "future proof" your app is to follow best practices in the design of your system to maximize loose coupling and separation of concerns. There is no part of your app that is safe from becoming obsolete, but much you can do to isolate code that becomes obsolete for reason X from code that doesn't necessarily have to be impacted by X.

However, I would contend that your concern should be less for the growth/scalability of your app than the growth rate of your own experience and capabilities. The mental block you describe sounds to me like either learning stagnation or awareness of many known unknowns without the strategy or tools to tackle them.

Frameworks are not particularly well suited to solving the "future-proofing" challenge, though they can provide relevant initial guidance to the inexperienced, usually via high-level design patterns like MVC. Rather, they tend to be more useful as ways to accelerate development by providing strong cohesion and often at the expense of tighter coupling. For example, suppose you use some framework-provided object-relational mapping system throughout the app to interact with your database, complete with caching-system integration. Maybe later you need to switch to a non-relational datastore and now everything that uses it is affected.

The mess you now have didn't come from what you used, but where you used it (probably pretty much everywhere on the back-end). How much better off you'll be if the code which renders a page never fetches the data it renders.

Suppose you want to add some little widget to a page which requires extra scripts and resources to work properly. If you're using a framework, you can ask "How does it want me to add the dependencies to a page for this thing?" If you're not, then the question is more open-ended: "What technical concerns am I touching that should be somehow separated?" That question takes more experience to answer, but here are some hints:

  • What would happen if tomorrow you moved all your static resources (scripts, images, etc.) to a separate server, content delivery network, etc., or started trying to package them all together to improve performance?
  • What would happen if you started placing this widget on different pages, or multiple instances of it on the same page?
  • How might you start performing A-B testing on different versions of the widget?

If any of this sounds overwhelming, then I'd suggest you should use a framework for now, not so much for the sake of your app but the sake of your own personal growth. Don't necessarily start over though. Instead use frameworks as curriculum to help guide the evolution of your app.

There are only two ways to learn. One is by trial and error, and the other is by learning from experience of others. Trial and error cannot be eliminated. Software development is by its very nature a continuous learning field and any code that doesn't do something new or different is by definition unnecessary. (Instead use the code that is already written.)

The trick is to minimize it by proactively seeking out pre-existing knowledge (strategies, best practices, and code/libraries/frameworks) throughout every step of the development process so you do not find yourself constantly re-inventing the wheel.

As for the app you are currently writing, however, your first concern should be simply to get it done with a minimum of mundane effort (which is kind of like code smell, but for the development process). Given the nature of human learning, the fastest way to achieve high quality is to start out with something. It is far easier to understand the goal when you can shape it by critiquing something you already have.

If you can accept that much of the code you write is a disposable learning process and necessary to find good designs, that will helpfully motivate you to keep at it. After all, it's the challenge of problem solving that makes software development engaging, and that challenge is ever-present if what you're doing is worthwhile (see "continuous learning" statement above).

5

Above all else, "scrapping the thing and starting over" is never an option ... after all, didn't you say that you have "a half-dozen clients?" Have you yet paused to consider what they might think of your pronouncement, given that they are right now (presumably) "perfectly happy with your work?!"

Here's an analogy that I like to use:

  • "My job is to build houses for people to live in, for people to build businesses in, and so on." My job is to make "those impossibly-tiny, over-glorified bits of sand" to do useful work. (Just as house-builders craft homes from gypsum wallboard, ceramic tile, concrete block and 2x4's.)

  • However, whereas the "nails" that house-builders use really haven't changed much in two hundred years (except to go from "square" to "round," and then to be made useful with pneumatic nailing-machines), the technology that we use is ever-changing and sometimes undergoes very profound change. ("So it goes.")

  • "Nonetheless, each house, once built, will forever-after be lived in." You can't evict them. Once you build it and hand over the keys, "it's not 'your' house anymore." It is what it right-now is, and it will stand for a very long time.

A large part of my business these days is to help clients to cope with software that was built ten, twenty, thirty or more years ago, using the "state of the art" technologies that existed in those days – (and which, ahem, I remember) – and which are still in service(!) today.

3

Ensuring something is future proof is almost impossible. Checking that app is scalable is not too hard though. You just need to write some performance test for the app and see how many clients it can handle. Writing tests will definitely make your app more future proof because you will be able to gauge how app behaves after you implement more changes into it.

wrt framework, I wouldn't be too worried performance/scalability wise. This is something you can easily check and most likely fix. The bigger issue is security. Web frameworks usually help you write proper authentication code, cookies, CSRF protection, etc. Especially given your lack of experience, better focus in that area.

3

I started writing a comment about learning frameworks, but eventually it turned into something looking more like an answer, so here it is.

Not knowing any frameworks seems like an issue. In basically any webdev job you will need to work with some framework. Learning another framework after you know one is not that big deal, but learning the first one may take a while - which is why employers may care about that. Avoiding frameworks may indicate not invented here syndrome, which is widely impractical approach.

As the main point of knowing your first frameworks is to learn a common language, perhaps just try learning something popular among your peers. You may try modifying some simple project written in a framework. Starting a project from scratch in a framework you don't know is a very ineffective way of learning.

Now, your actual question was about a specific project and porting it to a framework. For that, the answer seems to be: it depends, and we can't really tell you. However, porting stuff to a framework you don't know is almost certainly a bad idea, as you can't even know if it makes sense. Hence, it seems that you should leave it as-is, and revisit this decision at some point, once you know and like some framework. Other answers contain good points about what you should look for when making such decision.

Frax
  • 1,874
2

This article got a lot of attention on Hacker News 2.5 years ago: Write code that is easy to delete, not easy to extend. This perspective may or may not help you deal with your present codebase, but in the future, it could help prevent frustration that comes from perfectionism/over-engineering.

If we see ‘lines of code’ as ‘lines spent’, then when we delete lines of code, we are lowering the cost of maintenance. Instead of building re-usable software, we should try to build disposable software.

I don’t need to tell you that deleting code is more fun than writing it.

(emphasis mine)

The article's thread on Hacker News might also be worth a read.

-1

As far as making it future proof and applying scale & framework principles, it's a tall task to take on by yourself, I'd probably just not worry about it, but if you must:

Keep your code clean, follow SOLID, DRY principles > google.

Apply a load-balancer as soon as possible.

Stand up at least two web servers, handle load balancing scenarios in the code.

And last but not least, there's better stacks for handling a million users than LAMP, but I'm sure it's totally doable.

Case and point, see: https://stackoverflow.com/questions/1276/how-big-can-a-mysql-database-get-before-performance-starts-to-degrade The point is valid, but 10gb is trivial as a test subject.

Alexus
  • 2,398
RandomUs1r
  • 268
  • 3
  • 11