Wait, is this thing still alive?
Well, according to WordPress, I have about 20 active subscribers. That means there’s about 20 of you who are seeing this post pop up in your inbox making you think, “Wait.. what was that thing again?”
Yes, it’s been many years. KitchenPC was an amazing project and a highlight of my long career in tech. Being involved in the Seattle startup ecosystem was rewarding as well as a huge boost to my career trajectory. Everyone in tech should do at least one startup in their lives, even if it’s just a small side project.
With that said, I have some news! The last few weekends I’ve been trying to fix up and modernize the hugely outdated and legacy KitchenPC code base. Digging through the code, I’m amazed at how awesome a lot of it still is, but seeing how it’s written on the .NET 4.6 Framework (before .NET was called .NET Core and then just .NET again) and requires a Windows machine to build and run (I haven’t run Windows in years!), it was time to either fix up the code, or just call it a day and take the server offline. After all, I was paying Amazon about $50/mon just to host the thing on a Windows VM and Postgres RDS instance. Switching over to a Linux host would be far cheaper, but require me to bring up the code base to this decade’s tech stack. With that said, I have a few announcements.
The KitchenPC Open Source Framework is now netstandard2.0
The open source version of KitchenPC (which was basically pulled out of the KitchenPC website and made “generic” enough to run on any data store and configure for any purpose) has been brought up to date and now compiles with the latest C# compiler and framework.
KitchenPC Core Library is available on NuGet (Finally)
Before, you’d have to fork the repo and build the source if you really wanted to try out the project. I’m not sure how many people actually did this ever. I’d imagine 90% of them would have given up anyway.
The open source framework now builds on GitHub and automatically deploys to NuGet as a package anyone can reference:
<ItemGroup>
<PackageReference Include="KitchenPC.Core" Version="1.0.0" />
<PackageReference Include="KitchenPC.DB" Version="1.0.0" />
</ItemGroup>
It’s now a lot easier to try out the framework and use it in your own projects!
Imp is also open source!
Back when I first released the site, I remember getting a lot of comments on how fast it was. At the time, the .NET ecosystem was based around ASP.NET WebForms. Which I absolutely hated, and still hate to this day. The MVC Razor stuff is not much better. So, I wrote a proprietary framework called Imp, which stands for “In-Memory Pages”. The idea is there’s no HTML files on the file system, they’re all embedded as DLL resources. All the templates are stored as XML in memory and there’s a page compiler that converts that into an HTML output, substituting dynamic data where needed. I remember running JMeter tests on this framework and being able to serve up hundreds of pages per second, where WebForms would give me maybe 20.
The idea of this framework is that every URL is a class, and every URL parameter is a property of that class. There’s no complex routing or anything. For example, /Recipes/ViewRecipe/?id=123 would map to a class called Recipes.ViewRecipe which had a public int id property. Imp will instantiate that class and set the id property, then call the Render method. Render could just write out some data, or it could use a template that contains the actual HTML. Dynamic properties in the template would be mapped to methods in the class, for example if the template had <Dynamic.UserName /> it would call a method called UserName() on the class. It was insanely fast and also dirt simple, exactly what I needed for this site.
The old version that KitchenPC used was a managed handler configured in IIS, bypassing ASP.NET completely. The new open source version has been rewritten as ASP.NET Middleware, so it could be run is Kestrel or what not.
With that said, Imp has been pulled out of the KitchenPC website and made open source. It’s also packaged up on NuGet for anyone who wants to try it out and needs a very simple way to render HTML pages.
<ItemGroup>
<PackageReference Include="KitchenPC.Imp" Version="0.1.0" />
</ItemGroup>
I doubt I’ll work on it much (it does what I need), since there’s very little chance Imp takes off in popularity and becomes the next “thing”, but I’m also happy to take pull requests if those come along.
KitchenPC (the website) now uses the open source framework!
This one was a massive undertaking. When I wrote KitchenPC, the website and the core framework (which did all the fancy stuff with ingredients, recipes, natural language parsing, recipe modeling, etc) were basically wrapped up into one giant project. When I decided to open source KitchenPC, I pulled out all the guts (anything non website related) and packaged it up into a new project, which ended up on Github for the public. That new project had Fluent configuration, much more generic concepts, a completely abstracted data loading mechanism (you could run the engine without a database just off your file system for example), and also removed a bunch of concepts of the website (such as meal plans).
The website itself (which is still closed source) now uses the open source code engine directly. This required a lot of changes and improvements to the open source engine to support everything the website needs to do, but it’s also a fantastic “proof of concept” to show what you can actually build on the open source framework. I can now literally say you can build something like the KitchenPC website using the framework I’ve released.
The KitchenPC Website now runs on .NET 10
This was another massive undertaking. The major headache with this was the website was written using WCF, which was never ported to .NET Core or .NET 5 or above. I heavily relied on WCF for calling KitchenPC APIs, serializing JSON and error information, authentication, all that.
.NET WebApi is so much different, it took a ton of work to rewire everything. For example, WCF allows you to call web methods with multiple parameters, such as Recipe GetRecipe(guid recipeId, RecipeOptions options); whereas WebAPI only supports a single parameter, so you’d have to wrap everything up as an object. WCF also generates a very cool little JavaScript proxy script that just lets you call things on the server. I would include this proxy script (automatically generated on the server and cached) and in Javascript, just call KPCServer.GetRecipe(...); to load the data. This is a feature I loved so much, I ended up just writing the same feature for WebAPI in a mostly compatible way.
Modern Hosting for the website
In the beginning, I used RackSpace for hosting KitchenPC. The very first beta version as well as the public product launch used a VM on Rackspace which was a single Windows 2008 server running IIS and Postgres 9. A while later, I moved over to a VM on Amazon (Also Windows Server 2008 and never since upgraded!) and used Amazon RDS for the Postgres database, which made things a bit cheaper since Rackspace was around $80/mon.
Probably about a year or two ago, I kept getting nasty emails from Amazon saying I needed to update my Postgres version because “version 12” was being EOL’ed. There was one problem. The newer versions of Postgres used a TLS version that my ancient version of Nlpgsql (the Postgres driver for .NET) didn’t support. I didn’t even have a Windows machine to build KitchenPC on anymore and I had totally lost my entire setup for deploying site changes. It was actually easier to stop using Amazon RDS and just install Postgres 12 directly on the Windows VM and port my database there. So that’s what I did, which also means I’ve been using a super out of date version of Postgres. It was a bit cheaper though!
The new .NET 10 version of the website has been completely modernized. It’s built on a build server with GitHub Actions and hosted on Render, which allows running containerized applications. Render is hooked up to GitHub and when a new commit is pushed to main, it runs the Dockerfile and bundles up the app and runs it. Previously, I never even had CI/CD for KitchenPC! I just deployed directly from my computer using a PowerShell script I wrote. Half the time that script didn’t run right and I had to RDP into the server and screw with things.
Render also handles HTTPS. Don’t get me started on how much of a pain it’s been over the years to keep that Windows SSL cert up to date whenever it expired and trying to remember the slew of openssl commands required to convert PEM to PKCS. There was some hack you had to do as well to support the old encryption that Windows Server 2008 used. Render creates an SSL cert automatically, installs it, and keeps it up to date for free. I didn’t even do anything! It just did all that by itself.
So, I no longer have to buy an SSL cert for the site (So long, SSLs.com). The Render CLI is also amazing, allowing me to basically stream server logs in real time and make changes from the command line. Everything works right away out of the box, and oh BTW, it’s a lot cheaper than Amazon. I’m also using a Render Postgres instance for the database, which is version 18 and maintained and upgraded for me. No more worrying about any sort of server administration and deploying changes is super easy.
I also updated email notification handling. The old version of the site (which has probably been broken for years) ran a little background Windows Service called KPCQueue. The website would drop a file to the file system, the queue would pick it up, and send an email. If the queue crashed, it was fine because as soon as it would restart, it would see all the files and start processing where it left off. It used, I believe, some Google SMTP server I had setup to actually send the emails. It worked okay, but was pretty hacky.
The new website uses Resend, which holy crap is amazing. If you’re looking for a good way to send transactional emails, check out Resend. As a developer, this was exactly 100% what I needed. First, it’s free because I just don’t send enough emails to require one of their paid tiers. The developer support was crazy good, you just pull down a NuGet package and type a few lines of code. The web interface supports all the kind of template “mail merge” stuff you want to do (no need to port that stuff from KPCQueue) and provides various pretty graphs and stats to see what’s going on. I wrote all the code and configured my API key and made a basic email template and the whole thing worked on the very first try. This allowed me to kill the entire KPCQueue background service and implement “Share Recipe”, “Forgot Password” and “Welcome to KitchenPC!” emails directly in the website.
Hopefully more?
Don’t expect KitchenPC to come back full force. It was a fun project but I doubt it will really go anywhere. I also have a full time job that takes most of my time and mental energy. However, I’m hoping to contribute here and there to KitchenPC and its open source components on occasion and maybe even get this blog going again. It’s a fun side project and lets me try out new frameworks, technologies and services.
Hopefully the 20 of you reading this will not just go, “Ugh who is this? <unsubscribe>” or even worse, “Ugh who is this? <mark as spam>” but go check out the site again and maybe even dig around GitHub to see some of my work. That’s it for now!