1

Startup Context

A friend of mine recently asked me to be a part time software engineer for her startup which has yet to write any code. She is fairly serious and has already raised a fair bit of money. However, she currently doesn't need someone full time for development.

There are no legal issues with my current employer as they explicitly approve of secondary employment as long as it is reported.

Starting fast as solo developer

As I see it, the considerations for a single developer are substantially different from those for a team of say, 5.

  • Unit tests are less critical as every line of code is mine, making debugging easy. 100% test coverage has diminishing returns. However, one may need to go back later to finish them.
  • There are no merge considerations, as I am the only one doing commits.
  • Jenkins doesn't seem terribly useful as a solo dev as long as you run your unit tests.
  • Project management isn't really a thing as you are the team.

But all of these things could later become problems as well.

The question

How do I balance moving fast while still building a codebase that will effectively transition for growth?

I ideally would like to lead the dev team for this if it takes off, but if I get hit by a bus, I don't want her to be stuck with something useless.

Basically, if she raised a million dollars tomorrow and I was told to hire 4 juniors to help rush out the product, what should I be doing as a dev to make moving to that seamless as I write the code?

It is admittedly a broad question, but Stack Overflow and Reddit are filled with stories of technical debt or adjusting poorly to the growth of the technical team crippling startups. How do I avoid being that?

  • 3
    Your comments about "considerations for a single developer are substantially different from those for a team" are at best stupid and at worst arrogant. They show huge lack of understanding of what testing, CI/CD and good code quality mean. And while they are critical for a team, they are still useful for a single developer. – Euphoric Nov 12 at 7:54
  • 1
    As much as I disagree with the question's assertions and agree with @Euphoric's comment; I don't think this warrants downvoting or close voting. The question is well written and well elaborated and is perfectly answerable. It's counterproductive to downvote questions because they contain a mistake or misapprehension. – Flater Nov 12 at 12:13
5

Goal Setting

Regardless of if you are a half-man team or a 200 man team you need to be clear about what your goals are. Which mean yes there must be project management.

Now you don't need to draft a two hundred page word document with signatures, and graphs, and links to further reading. In fact please don't do that.

But you do need to be clear about:

  • where is the solution
  • why you value the solution
  • who is responsible for the solution
  • how you wish to travel to that solution
  • when you wish to arrive at the solution
  • what tools will help you arrive at the solution
  • which paths to that solution are you using

Those are not easy questions to answer. But you will need to answer them, and the answers will change overtime.

Knowing where the solution is will help you in evaluating off the shelf vs. cobbled together vs. in house solutions. Do you pay for an SQL Server licence, use MySQL, or write a dedicated persistence library? If your solution exists in the high availability category then it makes more sense to use SQL Server, or MySQL. It is doubtful you could write something more available. If you are in the embedded space then it might pay to role your own, as you can tailor exactly what you need. Without knowing where the solution is, you will make the mistake of putting go kart wheels on a rocket car, or building a lead balloon.

A solution is really only ever as good as its reason for existence. It might be well crafted, and a dream to install, but if its utility is once a year to replace a 10 second task it isn't very valuable. Knowing why the solution is needed will help you focus on making something beneficial. Without knowing you can only be useful by accident.

Responsibilities. Who decides when you work? How long you work? When you will work? Can you be called for support during your lunch break? Who makes the call about spending money? Who decides what the development process is? Who will arbitrate when a disagreement occurs? Right now she is your friend, but when you are discussing work, who is she, and who are you? Make sure the responsibilities are clear, you don't want to lead her on, but you also want her to know what you a reliable for. Also be clear about Who you will be expected to be. Are you comfortable acting as a manager? It is a different set of skills to developing software.

How are you going to work on this? Are you going to following TDD, BDD, some other design process? How are you going to allow parallel work? (Even by yourself chances are you will be asked to change focus, how are you handling the not yet production ready branch?) How are you tracking bugs, features, tasks? How are you demonstrating work achieved? How are you maintaining the operational system? How are you going to handle a bad deployment? When you answer how, you need to be aware of what you value, because how could be to write quick, dirty code. If you value good clean code, this is a sure-fire way to become dissatisfied, and will lead to you hating the code. Save yourself the trouble, hold yourself to what you value.

Odd, but businesses like to know when something will be achieved. So that they can schedule in all of the other whens that need to be achieved to get what they call a business value. Sometimes they need to do training, sometimes advertising, sometimes a booth or a demonstration. So part of this is projecting forward when things will be ready, and keeping the business up to date with that. So when are these big milestone likely to happen. Make estimates, and update them regularly. Play around a little and work out what system helps your estimates to be most accurate.

All of those what's that go into actually making, and operating software. There are a lot of them. They include everything from the code editor you will use, through to the domain name service, the printer, to the gui library, all of those "free" packages, etc... The specific what's will change, but you still need to know roughly what they are, or how to learn what they currently are. If you don't know it will be hard to make provision for a new developer. Oh, you need this credential, that runtime, oh and of course don't forget to install xyz. It also makes it difficult to create and maintain the prod and test systems, any automated tests, source/code versioning, project management, etc... I personally keep a tight reign on them by treating as much of these tools as code as possible and keep myself honest by rebuilding the various servers regularly from that code. The rest live in documentation with a regular scheduled review date twice a year.

Finally, which way are you headed right now. This is the short term objective inspired by all of the previous answers. Its a quite technical answer about your current activities. If you are comparing vendors then this would be compare vendors against these criteria. If you were bug hunting, it might be identify bug source, generate at least three solutions, evaluate against criteria, and schedule fix. Or maybe its implement these features, etc...

Moving Fast

Old saying my dad used to say a lot: Move quickly, not fast.

Anyone can move fast, just run - you will probably hit a wall or run off a cliff, and given how many directions there are, you will be running in the wrong direction, but boy are your legs moving!

But moving quickly means understanding the situation, identifying several paths, comparing the paths qualities, and picking the best solution in context. You may have to circle back later, but when you do its not because you were stupidly making work for yourself, its because the environment changed in a way you could not have forseen and hence was work you would have had to do anyway.

Professionalism

Would you buy a car that was assembled directly from an engineers stream of consciousness?

More importantly would you willingly sell a car that was assembled directly from your own stream of consciousness?

I personally wouldn't, even if I had some cyborg-augmentation that gave me access to the schematics of all previously constructed cars. At the very least I would assembly ten of them and test them first to prove to myself that those schematics were correct. I would assemble various sub-assemblies for various tests as well. And I certainly wouldn't sell if I couldn't clearly communicate how that car should be operated, and how it should maintained.

Essentially, don't be stupid. Those tests, that documentation, the schematic documents are there for a purpose. They are created precisely to address the issues you highlighted:

  • High level schematics enables fast growth as it lessens the learning curve from impossible/hard to hard/managable.
  • Tests provide a safety harness to alert the unwary to unexpected changes
  • Documentation provides curated knowledge enabling others to make wise decisions

And most importantly its your own mindset about these activities that forms the basis for the culture that later software developers will inherit and live in. Which code base will be your legacy?

Will future developers inherit well designed code, with supporting and up to date overviews, tests that are sound and legible, with documentation that captures the design choices and their reasonings?

Or are they going to get an unintelligible mass of code?

Tooling

Jenkins, like any other tool, it is only useful when it fulfils a purpose.

I'm a one man team too. I use Jenkins because I need a scheduler. It:

  • refreshes my SSL Certs,
  • runs daily verification builds to identify out of date packages and security issues,
  • runs my official builds because I can't be bothered to wait the ten minutes for Docker to download the latest images when my server can do it in 2 minutes, and provide a pretty unit test graph.

Not that I don't have the ability to do all of those things manually by running a script.

Branching

You will be branching, and more than likely merging too.

You will have:

  • emergencies come through,
  • larger features that need more bake time
  • features that are done, but have to be delayed as they are breaking, or need business sign off.
  • development script changes that need to be pushed into all of these branches to keep things ticking...

Not to mention, and you said it yourself, the need to be ready to hire 4 other developers. You will need to know how you are going to branch before they make a mess of things.

  • draft a two hundred page word document with signatures, and graphs, and links to further reading. You shouldn't be doing that in a team of 200 either. – Lie Ryan Nov 12 at 10:50
  • @LieRyan Agreed. – Kain0_0 Nov 12 at 23:19
3

The challenge that you express is the following:

Faster alone, further together
- African proverb

First of all, you shall not see testing as a luxury for bigger team. Writing some unit tests along with the software helps you:

  • to avoid loosing time on finding bugs later;
  • to do more tests and thus deliver higher quality despite your few resources,
  • to get a better design of your API and code structure: you’ll think sooner and with more criticism from the third party perspective.

Then, you shall not consider git as a luxury either:

  • who has never started to change something and an hour later regret to have started this mess? git will save you time!
  • of course, start with a simple one man workflow; do not peer review your own code ;-)

Finally, the technical dept is not a fatality: refactoring is your friend:

  • you’ll have to think a little bit about the design, but with the time pressure you’ll have to start fast. And once you’ve started and have inspiration, you’ll get caught in development.
  • Accept to start with an imperfect design. But as solo, you are extremely agile and easily agree with yourself. you can quickly refactor on the flow, getting rid of some initial design flaws. (Artists often work solo, and deliver masterpieces by cutting and changing until they’re happy with the result.)
  • later, with a team, you have the opportunity of a collective experience and think more together in less time than you would to cover the same thoughts alone.

    Finally, it’s th Tetris rule:

you have to decide quickly and accept bad decisions. But you have to clean the mess as quickly before the mess stacks up and game is over.

  • I want to stress another part of automated testing which is extremely useful imho: Regression Each test you write help you avoid a bug, find one where there is one and avoid that same bug to return. Each time you find a problem, write a test that fails, solve the problem and see your test fix itself. And think of why that bug appeared in first place, to avoid the same mistake in the future. – bracco23 Nov 12 at 15:12
1

Direct feedback

How to deliver fast and avoid growth challenges with a codebase?

These are commonly at odds with each other. Fast delivery can mean cutting corners and accruing technical debt, which leads to growth challenges when the codebase needs to adapt to new requirements.

The answer is a balance between the two, and it is contextual.

For example, I've worked for customers that were notorious scope creepers and we put a big stress on avoiding growth challenges. However, we've also done projects where it was apparent that there would be no further development after delivery (e.g. temporary solutions) and thus corners were cut where appropriate.

Unit tests are less critical as every line of code is mine, making debugging easy.

You today and you 6 months ago are two different developers just as much as you and Bob are different developers today.

You're effectively arguing that you're fast enough at debugging and thus don't need to test your code, which is massively missing the point of your tests often precluding the need to debug at all (if the tests are written with clear assertions).

I can't force you to write unit tests. If you're happy debugging, good for you. But I'm not agreeing that this is good practice.

That being said, this is again contextual. If I hack together a small console application for a particular short-term use case, I don't unit test it either. If I develop a codebases that is to be persisted and adapted long-term, I do write unit tests.

There are no merge considerations, as I am the only one doing commits.

That is assuming you get to work on each change uninterrupted. What happens if in the middle of implementing a change (already having committed some things), you find yourself waiting for information from the customer? Are you going to either wait until you get feedback, or undo all your commits?
Or what happens if you need to deploy production bugfixes while you're in the middle of implementing a change? Are you going to put the production bugfixes on hold until you're done with your change?

Your assertion precludes the possibility of not finishing a task (for whatever reason) and instead working on another task. If you do allow for switching tasks, then you are inherently opening yourself up to merge conflicts, regardless of how many people work on the project.

Jenkins doesn't seem terribly useful as a solo dev as long as you run your unit tests.

It's arrogant to think that you are above forgetting things or making mistakes. Sure, you may know that it's necessary to run your tests, but it's better to have Jenkins enforce it than it is to have to remember to do it and hope you remembered to do it for every deploy.

Project management isn't really a thing as you are the team.

Project management doesn't just exist for the team. It also exists to report back to the stakeholders, whether that's upper management or the customer. Just because you are a one man team doesn't mean that external people aren't interested in tracking your progress.

Basically, if she raised a million dollars tomorrow and I was told to hire 4 juniors to help rush out the product

Brook's law: "adding manpower to a late software project makes it later".

When you hire the 4 juniors, your productivity is going to tank as you have to take time out of your day to train these developers. Especially for juniors, even when they start developing, they're going to be slow at first, and prone to making mistakes and creating regressions or setbacks to your planning.

How do I balance moving fast while still building a codebase that will effectively transition for growth?

[..] stories of technical debt or adjusting poorly to the growth of the technical team crippling startups. How do I avoid being that?

By not moving fast. That is to say, by not trying to minimize the deadline by compromising your code quality.

Generally speaking, slow but steady wins the race, at least for marathons (i.e. long-term usage and adaptation of the software)


To summarize

Your solo developer arguments are all red flags to me. And before I delve into why: I started my career as a solo developer and ever assertion you've made, I've made in the past too. Don't think I'm dismissing your ideas because I have a different opinion than you.

Your ideas aren't wrong, but you're not thinking it through enough and accounting for reality/practicality. You may be fast at debugging, but not having to debug is even faster. You may skip on writing a test that you think is trivial, but it's going to bite you if you ever forget this untested logic in the future. You might skip on branching if you're the only dev, but you'll run into issues if your priorities change in the middle of implementing a change.
For a long-term project, all these time margins from your shortsighted mistakes will start adding up.

Let's use an example that is a bit clearer and not as tightly coupled with your current issue:

If my application never makes an error against FK constraints in the database, why would I even need to put FK constraints on my tables?

At the surface level, this appears to be correct. FK constraints are irrelevant when you never insert an invalid FK value. You don't need to validate data if you can guarantee it's never invalid.

But that is the same as saying that you don't need fire insurance as long as your house doesn't burn down, or that you don't need to wear your seat belt as long as you don't get into an accident. Technically correct, but completely missing the point that you cannot predict the future with any certainty.

All your solo developer assertions are analogous to the above FK example. "If I do it perfectly, I won't make mistakes" is a tautology, and it's absolutely missing the point that if anything goes wrong, the consequences will be more severe than if you had taken the time to implement the proper precautions.

Don't fall into the trap of becoming the rockstar developer who is too arrogant to think they can ever make a mistake. Mistakes happen, regardless of whether you're a junior or a senior. If you can't handle the idea of accounting for future mistakes you might make, you're in the wrong line of work.

0

Source control, unit tests, a build server. These things are designed to speed you up. Not slow you down.

Get your framework setup now at the begining so you will be developing on a highway instead of backroads

  1. Choose a stack and stick with it
  2. Source Control.
  3. Servers to deploy to
  4. Get your CI pipeline setup
  5. TESTS
  6. Security
  7. Develop Develop Develop. The blue sky is ahead of you.

Not only have you paved the road for rapid development, you have also positioned yourself to be able to take on new staff and benefit from the extra resource instantly.

Critically you are removing support tasks from your future work. Working out why a deployment failed, or debugging a feature you are sure used to work etc. These are massive time sinks that your dev framework will remove or minimise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.