Today software development looks pretty fragmented and complex depending on what angle you're coming at it from. I've spent the past decade building web apps, distributed systems, infrastructure and all sorts. My feeling is that as a developer there is still so much that stands in my way getting from some local piece of software to something that runs and scales in "production". I'm starting to rethink this from first principles and curious to know what others deem as the ideal developer experience for 2020.
Share your thoughts!
- The project should start up with one click or one command. It's fine if I need to configure credentials or something similar, but beyond that, your project should be so easy to start that your mom could do it. If the project requires me to locally install a database, configure ports, or anything of the like, that's a shining red flag that things are very wrong.
- The underlying architecture and rationale should be documented and this document should be reasonably up to date. Whoever is the lead developer on the project should be responsible for this. Not all details need to be covered, but the main principles and the driving business requirements behind it need to be clearly stated and up to date. If there's no broad documentation, I consider the project to already be off the rails, not just heading that way.
- There should be a concept of testing. You don't need to have tests yet, especially if you're still prototyping, but you need to have a very clear idea of what you will test, how, and how you'll get there.
- Formatting isn't a discussion point. Whatever stylistic preferences there are are covered by linting and automatic formatting. If I clone the project, it should be reasonably hard for me to do things the wrong way and fairly easy to do them the right way.
- Branch management, code review, etc. All of this falls in the same pot for me, no one should have the ability to push directly to master, all changes need to go through review, pass lint, tests, etc before they can be merged. Doesn't matter if you're the lead dev or a summer intern.
You'll notice that all of the above are procedural issues, not code specific issues. I firmly believe that by nailing the underlying process first, you make it easy to build good software and hard to build bad software.
I disagree here slightly. I think it's reasonable that a database setup may be necessary, especially if abstraction layers (ie. ORMs) aren't being used for SQL, and SQLite is not your database of choice. Sure, you could set up docker, but not every project adopts or even likes docker.
If you're also packaging your application as a container you can use container orchestration tools like `docker-compose` to compile your app and up a local dev environment with all your external dependencies with a single command (eg `docker-compose up`).
The thing is so over-engineered that they had to do a makefile that clones the project for you. And I don't know what they're doing, but the thing is unusable on a Mac (it's supposedly related to filesystem operations in Docker -- why are you doing so many?).
I could go on and on. I spent 2 days trying to make this work properly, but in the end I decided that if I need to do a Web store, I'll go with something else.
Frontend? ideally you'll provide the API setup like before, but I'll settle for a dev env online.
My experience is that technology has never stood in my way. It may be inconvenient, but I always find a way to work with it.
The thing that has always been in my way is other people. Always.
For me:
1. A boss who has a clue. Who has actually built software deployed to production at least once. Who understands the customer's business. Who manages things and leads people, not the other way around. Who gives me my assignments, the resources I'll need, and leaves me alone.
2. Project managers who know how to run projects.
3. Business analysts who know how to conduct analysis.
4. The decision to either go agile or not. No more sprints, stand-ups, scrum masters, product owners, retrospectives, etc, etc, etc, unless we do it completely and do it right.
5. Anyone, anywhere who writes something, anything down. No more, "Don't you remember when Sue asked Michael and he got Fred to tell us in that skype?" (My answer is always, "No.")
6. Any environment where I spend 90% of my time programming and 10% on overhead, not the other way around.
7. Authority to go along with my responsibility. I'm tired hitting every deadline and forced to wait weeks (or months!) for Peer Review, Code Review, Design Review, Standards Review, User Acceptance Testing, Integration Testing, Quality Review (against what standard?), Steering Committee approval, Leadership approval, approval from God herself...
8. A minimal acceptable competence level for my teammates, achieved by proper vetting (including tech interviews and tests). Software development is achieved as fast as the weakest link, not the strongest one.
9. No meetings!!! If it isn't written down, it isn't. If it is written down, you probably don't need to meet.
I could go one all day, but I'm late for a meeting. :-(
We also just started working with Blazor in production. There are still some rough edges in my opinion, but the conceptual model is very powerful. We currently use it in a limited internal system w/ server-side hosting model.
I do not think Blazor is an ideal technology for hosting netflix-scale applications, but for those highly-interactive/evented interfaces that you use for various business administration duties and expose to 10-10000 users, it's absolutely perfect. Being able to directly call C# business logic and subscribe to CLR events from your view logic is much more empowering than being forced to suck JSON through a straw, hoping client/server contracts are still lined up, and praying that all your complex XHR/websocket logic is pristine regarding error conditions and retries. Also, absolutely no NPM bullshit is required. I don't even have NodeJS installed on my machine anymore. All the javascript you will ever need can probably fit in a single static file. Our JS blazor interop shim is ~120 lines and it handles some incredibly complex client-side duties (get client rect for positioning elements server-side, subscribing and unsubscribing to events, etc).
However, "Visual Studio" is not my idea of the ideal developer experience... Maybe if the projects could be developed in VSCode
Got it.
Yeah, poo on Microsoft for being a successful capitalist entity, said the community of people who work for, want to work for, or find a living supporting FAANG or the advertising and VC ecosystem propping it up.
Syntax highlighting. Look up documentation at callsite. Jump to definition. Run a test from the editor. Debug executables from within the editor. Fuzzy find file by name (for instance, typing "pluginfancymixi" should turn up something at "project/Plugins/third_party/username/project_name/fancy_mixin.language"). Third-party plugin support. Ability to have per-repo configurations
* Searching code:
Should be faster than grepping a bunch of directories. Supports wildcard searching. Bonus: tooling support for finding identifiers, callsites, usages, etc
* Development environment:
Any executable or test can run in one step (zero if possible). If possible, should be able to run multiple instances of your app at once. For example, I should be able to leave a webserver running so that my code reviewer can test it without pulling the branch
* Team environment:
Small PRs. Quick reviews. Tuned balance between senior and junior engineers. Should have enough senior engineers that they don't feel overwhelmed by the mentorship+training part of their job.
Edited: formatting
I currently work on a project where infra is a complete mess, but another developer on my team takes care of everything, including setting up our own clandestine k8 cluster to work around the unreasonable limitations of the system we're supposed to be working on. I love him. The downside is that we're not compliant with all the rules we're supposed to comply with, but there's no way for us to comply and still do anything, so I'm happy we're doing stuff.
In an ideal situation, an infra team would take care of all of this for us and ensure it's easy for us to be compliant while still getting stuff done.
Beyond that, the ideal would be a unix-based shell, my preferred IDE (IntelliJ), the ability to install the dev tools I need, proper version control, clear, concise descriptions of what to implement, my own input on what and how to implement, and access to stakeholders/end-users.
* Node.js on backend, using a thin db layer (not an orm) like sequelize. My newer projects also use TypeScript on back end and share models with front end with a lerna setup
* React.js with TypeScript (default create-react-app setup) on frontend; multiple smaller apps for each business unit/functional area; some limited sharing of UI components between these apps (turns out not that much needs to be shared really)
* Everything in a mono repo and edited in VS.Code
* Deploy by building apps, gzipping backend and frontend into one tarball, then either:
- Ask my "release person" to copy it into the Windows server drive for test or production
- Run my own "release script" that scp's it to my Digital Ocean droplet and tells pm2 to restart the production application
My projects email me when something crashes in the back end and I run sentry.io to see what's gone wrong in the front end.
Why I find this to be a great developer experience:
* Simplicity. One language, easy to share things like e.g. validation between FE and BE, minimal cognitive burden when context switching; small apps = simple code; simple release system means I can get new features or bug fixes to users extremely fast with minimal fuss
* No CI pipelines or DevOps time sinks: this is effective because I'm a single developer; I also work on projects where a solid CI pipeline and infra as code adds value, but these things can also slow you down too
=====
In other words, what I feel makes me effective is using a modern language and ecosystem, but deploy it with methods from 10-15 years ago. :)
What happens if a client is interacting with the app at that very moment?
- Should not need an IDE ::: The system should be able to be developed without depending on a particular IDE or set of proprietary build tools.
- CLI tool-chain ::: The system should be able to be built and deployed using CLI tools, preferably open-source.
- Versioned deploys and Rollback ::: Each deployment should be versioned and rolling back should be fairly trivial (when things break this needs to be easy).
- Modular development ::: pieces of the system should be able to be developed individually without compiling/building the entire project.
- Poly Repositories ::: I've found mono-repos make every bit of code highly-coupled. CI tools like github actions, makes poly-repos much easier to manage and improve separation of concerns, dependency management and modularity of components.
- Feature based folder structure ::: Grouping source files by feature, rather than by file type.
- Design components for testing ::: Testing should be considered during development of components, then integration of testing later is much easier (decouple database logic, dependency inversion etc.).
- Encapsulation of libraries ::: I personally prefer that most external libraries are encapsulated within wrapper classes, in order to insulate them from directly touching different parts of the system (ideally)
- Cross-platform should be trivial ::: Web-based applications easily achieve this, but so do many scripting languages etc. If building for different platforms is unreliable/impossible than that's not ideal.
These things vary in importance from person to person, but they're important to me.
I've learned to actively loathe getting started on a new feature for one of my sites. The typical process starts by trying to make a simple change to the codebase, only to learn that some tool needs updating (who knows why), but only after digging around for half an hour trying to figure out why something simple doesn't work. I then try to update the tool, but the update doesn't work, because something else has changed on my dev machine, making the update incompatible. After trying to update everything for a couple of hours, I sometimes manage to get the development environment working again, at which time I actually start coding. Sometimes I just give up and try again in a couple of months.
In the good old days, I would just open a code editor and edit a PHP file, then upload via FTP.
If only it were that simple now. My ideal developer experience would be to simply be able to open my computer and start coding – even if I hadn't worked on a project in a few years.
[1] https://github.com/features/codespaces