HNHacker News
TopNewBestAskShowJobs

jaysylvester

33 karma · joined May 26, 2024

https://jaysylvester.com
submissionscomments
jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
Just wanted to thank everyone for helping citizen get its first 100 stars on Github.

Looking forward to your feedback.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
I used to fall into the trap of always wanting to build everything myself, which ironically led to me building a framework so I wouldn't have to do that over and over. So I agree totally.

Every "framework" available when I started with Node seemed to be a collection of loose opinions regarding Node best practices, lightly dusted with syntactic sugar. Functionality I considered table stakes for web apps usually involved choosing from several middleware packages with different maintainers and different syntax. Didn't like it.

Thanks for the compliments. I hope the community sees the value.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
I think the first request isn't all that bad. Something like:

1. Transpile .ts modules to .js on app startup (development mode only)

2. Import .js modules into citizen as it does today

3. Watch for updates to .ts files and transpile to .js

4. Watch for updates to .js files and reload the module as it does today

I'm assuming you wouldn't want the transpiled JS modules sitting alongside their TS sources due to cleanliness, so I'd have to figure that part out.

The second request, no idea, since I've never written a test in my life :)

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
In reviewing the Adonis docs, I think the biggest difference between citizen and Adonis is convention over configuration.

citizen expects you to put certain things in certain places so it can handle all the imports, execution, and flow control for you. Adonis requires you to be far more explicit.

For example, in Adonis, you define routes within a router file, whereas in citizen, routes are implied by the existence of controllers and actions/handlers in the appropriate locations.

citizen does have config files (and controller/action config overwrites) for things that require an explicit setting, but I tried to keep that to a minimum.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
Guess I should've posted it on HN much sooner. I shared it on social media years ago, but it never got much traction (I have few followers).
jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
Question: would you expect it (or want it) to use a runner or a transpiler? Or does it not matter?
jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
I don't know what's out there that's similar to citizen, honestly. I didn't set out to create competition for existing frameworks; I just built the stuff I found useful for my own projects and think it's finally at a point where others might find it useful also.

Basically, I wasn't a fan of what was available 10 years ago, so I built what I needed and didn't pay much attention to what others were doing.

One of my fears in sharing it widely was getting a response like, "You're about 5 years late, frameworks X, Y, and Z do all these things already." But based on some of the comments, it seems like citizen offers something that others don't.

What I like about citizen is that it provides enough structure to get started, keep my code organized, and focus on what I'm building as opposed to how, while remaining flexible and hands-on enough for me to feel like I'm actually writing code and not just gluing together everybody else's code.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
As you've noted, citizen is clearly written to handle pretty much everything within the application server itself, which stems from my own particular use cases.

I suppose that's my anti-pitch: citizen caters to apps that can run comfortably on a single instance and accommodate storage within that instance, or have a web server in front that can distribute clients across multiple app servers and keep each client on the same instance so as to preserve user sessions across requests.

Now that I consider it feature-rich enough for general use by other devs, I'm thinking about how it could be expanded to accommodate external storage solutions and make the app server stateless.

I opened this months ago and it directly addresses your point:

https://github.com/jaysylvester/citizen/issues/120

The same question applies to citizen's built-in caching, but if I uncouple that from the app server, I have to ask why the dev wouldn't just use a third-party caching solution instead.

As for external data, I deliberately left models wide open and un-opinionated. They're modules you can put anything into. For my own apps, I use node-postgres, and my models contain all my SQL queries and interact directly with the database. citizen doesn't interact with the model in any way besides storing the module in the global scope so it can be retrieved without importing it (which I do to support hot module reloading).

Curious to see what you've been working on and your approach.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
The scenario you described is exactly how I host my sites now (Debian on DO).

I've seen numerous engineers advocate for letting the app crash (or at least gracefully shutting it down), capturing the error, and restarting. Errors crash the Node process by design after all. Perhaps it's not as prevalent as it used to be, but it was certainly considered acceptable and even desirable for a time to let the app crash and restart it with pm2, forever, etc. since an error could leave the app in an unknown state.

citizen has a config option for keeping the app running or exiting the process in the event of an error, so it's up to the dev.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
Thanks!

"Fun" and "comfortable" haven't applied to web dev for a long time in my opinion, and my preference is to keep it as simple and enjoyable as possible.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
It mostly means keeping routing/rendering/etc. on the server rather than client. My preference has always been to let the server render the initial request in full (feed the client an entire HTML document) and then update on the client side as necessary (which could be data via JSON or chunks of HTML, whichever makes sense) with progressive enhancement and minimal JS as the goal.

You can of course build an API with citizen that only returns JSON responses and do all the rendering on the client if you like. It's meant to be flexible that way. Basically, the client-side stuff is completely up to you. I've toyed with the idea of building a client-side companion library that wires everything up so server citizen and client citizen talk to each other and do what I described in the previous paragraph automagically.

I started citizen a decade ago, so many options available today were either non-existent or in their infancy then. I haven't performed a competitive analysis to compare features with other frameworks. You nailed it though on the lack of kitchen-sink-type frameworks in Node (especially 10 years ago), which is why I built citizen. And I didn't like the idea of depending on so many third-party packages.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
At least I stopped deploying site updates via FTP.
jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
No tests yet, that's been on my list since the beginning and I now have the incentive to work on them:

https://github.com/jaysylvester/citizen/issues/24

I don't use TypeScript myself, but based on what I know, I don't think it would be difficult to add support. I just opened an issue to track it:

https://github.com/jaysylvester/citizen/issues/131

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
That's a fair observation. I only include it because the Node way of doing things seems to be "just let the process crash and restart it", and that's been a tough concept for me to accept. I'm particularly proud of error handling in citizen and want it to be as much like an old-school app server as possible.

I still use pm2 on the aforementioned site just in case though, and maybe seeing that extended process uptime is just a feel-good exercise, but still worth mentioning.

I've been meaning to do real performance testing and keep pushing it off because it's been adequate for my needs.

jaysylvester··on Show HN: Citizen – A Node.js web app framework for fans of classic app servers
Thank you! I try to be thorough. Getting to be a bit much for a readme though, probably deserves its own site.