https://www.Kandoop.com, a productivity platform (better Evernote + Trello + WordPress-ish for custom feeds). It does a bunch of good stuff.
AWS, PostgreSQL + Redis + S3, BE is 100% Python-based Lambda functions, FE is browser-native WebComponents (no frameworks), mobile app is the same FE code wrapped with Cordova, on Google Play and Apple App Store.
Serverless functions are my #1 tip to reduce low-value maintenance time for solo devs / small teams.
My new product, Kandoop (at https://www.Kandoop.com and on the app stores). It uses a cards-in-boards model, and is intended to be full life-cycle from an individual with an idea, to team task/project management, and curated publishing (custom "news feeds" that are intended to be a clean view for executive stakeholders, partners or customers). One of the key features is that "lists" of cards (boards contain lists, lists contain cards) can be attached to more than one board, so everyone can create the optimized view for their role. Example of when that's helpful include manager <-> direct-reports task views, where the manager wants everyone's list in a single view, but can't share the whole board with everyone due to private info. So the lists are shared with the relevant team member, who can put that list in their own personal to-do board, while the manager can create a board with all of their direct reports' lists.
My app CardBoard (https://www.cardboard.team/) is no-framework vanilla js. This is a large-ish codebase with a lot of functionality, and the same code is wrapped with apache cordova for both iOS and Android apps. In 2022, browser-native WebComponents (addresses encapsulation, code organization, and re-use) with no frameworks is a hill I'd die on.
The difference between an agency/consultancy (selling services) and a product company is enormous. There are other advocates here for product, but since the $100k you mentioned is probably for a services engagement (you don't have a product yet), I'll share a warning about that model for a startup. When your business sells services, you essentially become a broker between people who need a type of work (your customers), and people who can do a type of work (your employees and sub-contractors). The health of the business, then, is tightly dependent on the relationship between the demand from your customers, and the availability and cost of the people with the right skills to execute the work. Assuming you're already in a good place to gauge the customer demand, my warning is about staffing to execute the work. It's easy to imagine that legions of the experts you've worked with previously will be inspired to join you, but you'd be surprised how untrue that can be (or possible but more expensive, due to the risks of a smaller company). Yes, it's possible to create a great, sustainable services business, but it's important to be aware of the challenges you can face with staffing, retention, keeping customers happy, and doing it all within a commercially viable margin.
Off the tools topic, but IMO the most important consideration: the mindset should be entirely about understanding the existing approach, conventions and philosophy, vs a critical assessment leading to "this needs to be modernized". Particularly on small-medium codebases with smaller teams, I've seen projects be fundamentally damaged by new, well-meaning devs who bypass most of the hard-slog of really understanding the existing how/why, and instead try to jump to the more comfortable space of using tooling or approaches they're more familiar with. There is certainly a place for that, but depending on the project, that might be 3 to 6 months later. Programmers need to appreciate the power and consequences for management and non-programming team members (product) when a new dev brings a condemning assessment of an existing codebase after one or two weeks.
What really undermines that necessity is this whole thing of having new developers "hit the ground running", meaning they're not just given light tasks for the first few months to help them understand the codebase and philosophy, but full blown important tasks with deadlines. I've had this happen to me more than once and I think it kind of acts to gaslight the new developer into initially thinking that the problem is them and not the codebase. Although I made it through building out a context menu UI from scratch as a first task on a previous project I was hired on to, that probably wasn't the best thing for that reason.
I get that new devs need a mindset to understand the existing approaches, but tossing them right into the middle of the foray actually makes things worse.
And yeah, teams need to be able to respect and respond to the frustrations of new developers. If a new developer, especially a senior developer, needs hours or days and multiple approvals to do something as simple as change a string, for instance, something is seriously wrong and you need to actually re-evaluate what everyone is doing.
Yes, I've experienced that exact phenomenon, and it's amazing how little people are concerned by that kind of thing. I'm not the greatest programmer in the world by any means, but I know how to change a string and when a design is ridiculously inefficient. Yes, there was a project I was on-boarded to where one of the tasks was changing how a string appeared in the UI; it turned out there was a shared library carrying the target string, but it wasn't exactly obvious that was where the string was coming from, and multiple other projects were using that library and so the review process needed to apply to all projects involved. For some reason, although a role was delegated to deploying the app itself, it's up to individual devs to build the library and register it as an NPM package, and there was a tight protocol around. Because of the toolchain, the library was not easy to test with an app locally. So it ended up that changing a string could take several hours or even days, especially if someone wanted to squeeze in another string change into that same task.
As a developer who just joined a team, what are you really supposed to do? Just plow through believing that there's a good reason for the madness?
Agreed on the hit-the-ground-running problem. Related to your final point, assuming that you're not coming into a situation well-known by all parties to be a shit show, I think there needs to be a Minimum Patience Period (probably relative to the size/complexity of the project, window given to get up to speed, etc). For example, if the product is working well, the release cadence is acceptable, the defect rate is low, etc, I think the prior devs have earned a reasonable benefit-of-the-doubt MPP that a new dev should accommodate for learning the existing approach and rationales. I've seen a senior dev completely change tooling and build process for a "fine" app at the end of their second week. All good ideas in the right time, but...
> I think there needs to be a Minimum Patience Period
100%. That can be very, very hard, but yes. It's also got to go both ways. New devs need an MPP for the project, and the rest of the team and management needs an MPP in relation to the new dev.
> if the product is working well, the release cadence is acceptable, the defect rate is low, etc, I think the prior devs have earned a reasonable benefit-of-the-doubt MPP that a new dev should accommodate for learning the existing approach and rationales.
That's often true, though release cadence and defects in production can also be low if you hire a crapton of devs to work on the same project despite any present dysfunction. So that may be something to keep in mind, too. And maybe that means the new dev realizes that they need to change their expectations such that the underpinnings of a project are conceptually flawed and that it's really their job to deal with that given that the company has plenty of revenue that they can just hire however many devs it takes to keep things running.
> I've seen a senior dev completely change tooling and build process for a "fine" app at the end of their second week. All good ideas in the right time, but...
Haha, ohhh yes, I've been on both sides of that coin. This problem really highlights how the difficult part of coding isn't so much the code but the people (and in a good way!). I've made that mistake of coming in and fiddling with, kind of wrecking, the existing process. Some of that is overambition, some of it is the lack of formal training in our field, and some of it is the ambiguity of roles that is quite common. The word "senior" can illicit this self image that you can and should make sweeping decisions. I've appreciated it when teams have been able to communicate expectations upon joining rather than just saying "it's up to you" for everything; that is until you actually do change something like a part of the toolchain, resulting in technical and interpersonal issues.
In my next role as a senior, I plan on going in with the mindset of not changing the foundation of a project except requesting removing the spandrels and canards that no longer serve a purpose.
I’ve been working on an SPA built with no frameworks, a lot of WebComponents, and almost zero 3rd party code, and it’s fantastic. Package managers and frameworks have a lot of holdover momentum from an era when they were far more necessary, and I think a lot of teams and individuals have unacknowledged PTSD that prevents them from stripping out these legacy comfort & safety nets. Plus, it’s likely also a comfort for managers to believe a team is working within some sort of opinionated 3rd party-supplied guardrails.
How did you go about establishing structure and patterns that are typically enforced by frameworks? Was Web Components a big piece of that or were there also other major patterns you incorporated?
Great question. WC doesn’t provide any architectural structure beyond code encapsulation for your UI widgets. But this alone gets you per-feature sandboxing, even more strictly if you use the shadowdom to get runtime isolation as well (I typically don’t, but it’s a good fit for many solutions). This allows you to move ahead pretty quickly, knowing you can tear out and replace these elements easily if you got it wrong or the needs change, without core changes to the app. Yes, you still need foundational services like data access & caching, personalization, etc, which sit outside of WC, but the “best way” for those things is typically very tied to what you’re trying to build. So for those, I typically just start with a functional “sketch” of each service with a lot of code separation, and let the architecture emerge through iterations of refactoring as I start to understand what I need. The biggest refactor problems tend to have to do with precedence of rules and order of code execution, with the biggest issues at initial load as arrival scenarios get more complicated. But no framework is going to solve those problems optimally for your app, and more likely, the frameworks create more obstacles to doing it well. And then there’s always the problem that your devs need to be really knowledgeable in the framework to not apply it badly.
>How did you go about establishing structure and patterns that are typically enforced by frameworks?
I know PHP gets a lot of flak, but I think this is an excellent example of how that can be accomplished from a backend perspective using proven libraries.
In the example, the developer uses a library for most of the main features e.g. flip/whoops and FastRoute. By pulling together these libraries, in effect, they have created their own framework have they not?
generally I do this:
* make components that take responsibility for a bucket of concerns: like the app (track the app state--user, etc); then views (generic pages, more complex main-section things, etc); then more granular composable stuff like a highly specialized button (arbitrary example);
* communicate state changes up via events, for global or highly generalized coordination between anything just handle that on the window/self (setup/undo on the component lifecycle methods); send/intercept/capture these messages on the event.detail (use composition and bubbling);
* stick to first-principles: KISS, YAGNI; don't over-engineer your stuff, use encapsulation, if you don't need a shadowRoot it's not required, or use slotting..., use global styles where that's appropriate, use shadow encapsulation of styles where that's separately appropriate--keep those concerns separate and use common sense about appropriate separation of concerns;
* don't automate or use external libraries or anything fancy unless it has a clear self-apparent business case (for my work or the customer or the business); forget all the assumptions of the frontend community--it's mostly noise
The biggest crimes of web frameworks is they take you away into abstraction land away from the actual standards and they complexify simplicity, all of that under the guise of being more "standard" and more "simple". It is one of the greatest lies ever sold.
I remember how .NET WebForms and lots of Java boilerplate frameworks did that early on, or browsers breaking standards, they wanted developer lock-in just like web frameworks of today. They wanted to keep developers dumb by being "simple" as long as you stay in their walled garden where they handle the standards. No thanks...
I have been developing javascript for decades and I actually liked the original less Java like boilerplate of the previous iterations, and you can still do that. The people that push frameworks aren't always trying to make things more simple, they want control, lock-in and domain ownership. The last tool to really simplify in javascript was jquery and most of that is browser level now including selection the killer feature of jquery across all those document.all/document.layer days of pain. Those days are over, simplicity is being complexified now.
Tools like jquery and even Flash or other plugins were platform pushers that got the web to the place we have now which is better than ever for web standards, yet we have all these bloated frameworks on top now. In a way it is a bit like the xkcd comic with so many standards, just to not do javascript people built thousands of frameworks on top to "simplify" the standards that are simple now.
While web frameworks may have been needed for a time, and in certain team based scenarios, they are a crutch, a maintenance problem long term, they take actual standards out of experience and the worst is they make the simple complex. Web frameworks have become the DLL hell or dependency deepend that used to be used to attack other platforms. .NET and Java have less bloat now and are moving more standard, while javascript web frameworks only pretend to.
The web standards of today are amazing and take away the nee for frameworks today: from templating to html templates [1], vanilla javascript with classes [2] and async [3] and better api access like fetch [4] and browser support for vdom with shadow dom [5], components with WebComponents [6][7], css now with lots of additions like variables [8] transitions[9]/animations[10], flex and media queries, canvas/svg/etc for interactivity, and so much more. There is little need to use frameworks except to sell books and conferences and keep developers locked in.
As developers/engineers, the job is taking complexity and simplifying, ask yourself if your framework abstraction is doing that above actual standards that is a pain long term to maintain. Web frameworks were supposed to work together, they are now behemoth monoliths that limit dynamic and fluid systems that scripting are supposed to bring. People went out and made a scripting language for glue into Java boilerplate...
In areas like targeting a certain javascript ECMA version or polyfills, those are still worthy, the other pile of verbose bloat abstraction that is there is just that, a pile of "verbloat". "Verbloat" is a new word to define frameworks of today sold in as small helpers to replace jquery, that have grown to the size of dev lock-in tar pits. No developer in their right mind would use this for products/projects they control unless they have to at this point.
Basically this video summarizes the absolute unnecessary adventure of web frameworks and provides some comic relief to the absurdity of it all. [11]
One yet-to-be-mentioned element here is the dynamic of developer preference and resistance. As systems bifurcate into relatively cookie-cutter "lego"-like technical components (the Wixification of the entire stack via cloud, frameworks and no-code), vs the heavy-lift coding to make the framework "legos" themselves, a lot of the fun development is going to go away (development with a direct end-user feedback loop and the reward of solving some real-world problem). This dynamic also eliminates a good entry point for developers (basic apps and web sites), which allow them to build the knowledge to create and love those more sophisticated re-useable legos, because they understand the true pain of solving those original problems without them. I predict a big, negative impact on the future population of developers arriving to software from "creative" entry points, like design, marketing, or finance, because the bridge will be gone. What will be left are only formally educated engineers.
AWS, PostgreSQL + Redis + S3, BE is 100% Python-based Lambda functions, FE is browser-native WebComponents (no frameworks), mobile app is the same FE code wrapped with Cordova, on Google Play and Apple App Store.
Serverless functions are my #1 tip to reduce low-value maintenance time for solo devs / small teams.