Blog
Feb 5, 2025 - 10 MIN READ
10 Coding Practices I Follow on Every Project (So You Don’t Have To Regret Hiring Me)

10 Coding Practices I Follow on Every Project (So You Don’t Have To Regret Hiring Me)

The non‑negotiable coding habits I use on client and personal projects—testing, git hygiene, documentation and performance.

Kadiri Success

Kadiri Success

TL;DR

  • These 10 habits are how I avoid “it works on my machine” drama.
  • I optimise for readability first, performance second (with measurements).
  • Git history must tell the story; no “final-final-v2” commits.
  • Tests, linting and basic monitoring are part of “done”, not an afterthought.
  • If a new teammate can’t ship in day one, the structure is wrong.

1. Start from the user and the constraints

Before touching code, I write down three things:

  • Who is this for?
  • What does “fast enough” mean in this context?
  • What constraints are we under? (time, budget, infra, team)

This gives me a simple decision filter:

  • If a micro-optimisation doesn’t move user outcomes, I skip it.
  • If a feature makes onboarding harder with little gain, I push back.

Code is only “good” inside the context of the problem it solves.


2. Favour boring, predictable architecture

I’d rather have:

  • A readable, slightly repetitive Nuxt page structure.
  • A simple service layer with clear boundaries.

than:

  • A clever meta-framework nobody wants to touch in six months.

Patterns I use a lot:

  • Clear separation of concerns: pages vs components vs composables.
  • Dedicated directories for API, content and utilities.
  • One “source of truth” for each piece of data (no copy-paste configs).

If a new dev can’t guess where a file lives, the structure needs work.


3. Make types your first line of defence

I use TypeScript as a design tool, not just a safety net:

  • Define types for API responses and props early.
  • Model nullable cases explicitly instead of sprinkling ! everywhere.
  • Prefer zod or similar runtime validation at boundaries.

This reduces:

  • “undefined is not a function” bugs.
  • Confusion about what a function expects or returns.
  • Surprises when backend contracts change.

Strong types are a free specification your future self will thank you for.


4. Treat git history as documentation

My rules:

  • One logical change per commit.
  • Commit messages describe intent, not implementation.
  • Branches are small and short-lived.

Examples:

  • feat: add RSVP guest limit with validation
  • fix: debounce search to reduce API calls
  • changes
  • fix stuff

Good history lets you:

  • Blame without drama.
  • Revert safely.
  • Onboard new people quickly.

5. Write tests where they pay off the most

I don’t test everything blindly. I test:

  • Core business rules (money, access control, bookings).
  • Complex pure functions (formatters, calculators, mappers).
  • Critical flows (checkout, sign-up, contact).

I prefer:

  • Fast unit tests for logic.
  • A few end-to-end tests to protect critical journeys.

And I always:

  • Run tests before refactors.
  • Add tests when fixing bugs to avoid regressions.

The goal is confidence, not 100 % coverage for its own sake.


6. Let automation enforce code style, not humans

Style debates waste human energy. Tools don’t argue.

I use:

  • ESLint and formatters to enforce consistency.
  • Pre-commit hooks or CI checks to block broken code.

This means:

  • Code reviews focus on architecture, UX and performance.
  • Developers don’t nitpick each other’s spacing or commas.

Once the rules are agreed, the tools do the enforcement.


7. Measure performance instead of guessing

Instead of “this feels fast enough”, I:

  • Use Lighthouse and WebPageTest for frontends.
  • Use logs and tracing for backend endpoints.

On portfolios and landing pages, I care most about:

  • First Contentful Paint.
  • Largest Contentful Paint.
  • Interaction to Next Paint.

I optimise:

  • Images first.
  • JavaScript bundle size second.
  • Third-party scripts last.

Performance is a feature, not a nice-to-have.


8. Design for debugging from day one

I ask: “When this breaks in production, how will we know why?”

So I:

  • Attach identifiers to important requests and logs.
  • Use structured logging, not random console output.
  • Keep error messages helpful but not sensitive.

This turns “it’s broken” into:

  • “This endpoint is returning a 500 for group X with payload Y.”

It saves hours of guesswork when things inevitably go wrong.


9. Leave the campsite cleaner than you found it

When I touch old code, I try to:

  • Extract one messy block into a small function.
  • Rename one confusing variable to something clearer.
  • Add one missing test for a known edge case.

I don’t rewrite everything. I just improve the area I already have open.

Over time, this:

  • Reduces complexity.
  • Improves morale.
  • Makes “legacy” code less scary.

10. Communicate clearly, early and often

The best code can still fail a project if communication is poor.

My habits:

  • Share small updates instead of going silent for days.
  • Raise risks as soon as I see them, not after a deadline slips.
  • Translate technical trade-offs into business language.

Examples:

  • “We can hit the deadline if we skip feature X and add it later.”
  • “This API choice saves us money but adds 80 ms latency—worth it?”

Good developers ship code; great developers build trust.


Final thoughts

These 10 practices are simple, but they compound:

  • Fewer bugs.
  • Faster onboarding.
  • Happier users.

If you’re reading this as a potential client or teammate, this is the standard I bring to every project on this portfolio.

Built by CodeByQuan • © 2026