Development Tech

Loading environment variables in code: the simple way

Read on for a solution to loading environment variables from a .env file. The code is for Kotlin, but should be easy to replicate in other stacks as well. No frameworks, low complexity. 🙂

I try to not add frameworks or libraries unless they add great value. Of course I don’t want to re-invent the wheel, but there is always more complexity and limitations to the libraries than you first think. And then it is a chore to replace it.

Start small and expand. 🙂

A lot of things are really not that complex to write code for. Application configs are one of those things. Even working across Gradle and local development in your IDE.

Get a variable from a file, if it exists in the ENV; use that instead. It’s that simple. 🙂 Need something a bit fancier? Just extend the code, you can do it. 😉

So here’s the Kotlin code for a config with the code to load it. Just one key here, but you get the gist of it:

data class ApplicationConfig(
    val lookupApiKey: String
) {

    companion object {
        fun load(): ApplicationConfig {

            fun Map<String, String>.envOrLookup(key: String): String {
                return System.getenv(key) ?: this[key]!!

            val envVars: Map<String, String> = envFile().let { envFile ->
                if (envFile.exists()) {
                        .map { it.split("=") }
                        .filter { it.size == 2 }
                        .associate { it.first().trim() to it.last().trim() }
                } else emptyMap()

            return ApplicationConfig(
                lookupApiKey = envVars.envOrLookup("LOOKUP_API_KEY")


The config is loaded in tests and in the KTor setup by calling the load function like this:

fun Application.module() {

    // Manual dependency injection :) Usually smart to find a separate place to do this from KTor
    val config = ApplicationConfig.load()

    val mainPage = MainPage(LookupClient(config.lookupApiKey))
    val selectedPage = SelectedPage()

    // Load pages
    configurePageRoutes(mainPage, selectedPage)

As a bonus, you also see manual dependency injection. It really works. 🙂 And it really helps keeping the compiler give real feedback when something changed that needs to be updated.

You can find a complete application with this code working here:

Thoughts? Let me know.

This is just one of many things I do to avoid complexity so stay tuned and subscribe for the next thing.


Replacing legacy systems: Proxy to learn and control

TL;DR – Create a custom proxy to make sure you know how the old system behaves and can transition off it in a controlled manner.

A couple of weeks back I held a talk at JavaZone about replacing legacy systems (Norwegian only, sorry). One of the techniques I talked about that seemed to spark an interest was creating a custom proxy to take control and figure out what the old system does.

Not a dedicated proxy like Nginx or Apache, a custom proxy in the language and technology you are comfortable with. It can ease the replacement and transition a lot.

For us that was KTor Server+Client.


When you have a system with a Webapp, Mobileapp and API like this:

You can take control of the system by introducing a proxy like this:

Simple as that. 😉 HTTP request in, HTTP request out, receive response and send response back to the source. A bit of fiddling around, but you essentially copy everything forward and back. Headers, Method, response codes and of course body.

The figure above also shows how we used the proxy to double check some data results in the DB before switching out the legacy system (the dotted lines).


By creating a custom proxy you can monitor, log, analyze and even compare results. All in your preferred development language.

When you gain insights into how your system is working, you can manage which parts controls and receives each call.

Wan’t to switch over based on user-id? That’s a simple conditional statement in your proxy code.

Switch gradually based on endpoints? Even easier, just change which system is the recipient for your call.

Subscribe new content:


We used KTor Server+Client because it made it easier to know that coroutines were handled correctly but you could also use OKHttp as a client if you wanted.

Be careful with big payloads though, stream the results as a default, and only load the body into memory if you know the size and actually need to analyze or modify (don’t) it.

I don’t have the proxy as an example myself but this doesn’t look like a bad starting point:


Yeah, that’s harder. But still just streams of bytes back and forth. Even Cobol Copybooks has a format that can be parsed. 🙂

Happy migrating 😉

What’s your best techniques for migrating off legacy systems?

Architecture Development Tech Web

Full stack development with KTor and HTMX ❤️

Sometimes it feels like I have been yak shaving for the last 20 years. Well, not entirely. But things like Rules Engines, SOA, App Servers and debugging Hibernate comes to mind. 😉

On the back end, things have gotten better over time. But on the front end it, feels a bit like it is history repeating. While it is impressive what you can do in React. React and all the accompanying tools is too complex for many normal web applications.

So when I discovered HTMX it really tickled my interest to see how I could combine this into an efficient development flow. Back to basics. Hypermedia and HTML. 🙂

And I think I have a pretty decent starting point in the Github repo linked below. 🙂

A full stack environment with Kotlin, KTor and HTMX. Everything loaded, compiled and packaged with Gradle. Compile in IDEA to see the changes full stack.

The following repo contains a running example (just do ./gradlew run to test it) and a semi-detailed Readme:

You can try the “application” here (initial load might be a little slow as it is on free which suspends inactive processes):

This holds real promise, and I hope I get to work with this for real in production soon. 🙂

Thoughts? 🙂

After doing this I discovered that there is a similar example linked directly from the HTMX site. Nice one 🙂

Subscribe for more: