Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]

Krzysztof Kowalczyk blog

Krzysztof Kowalczyk...
Implementing Notion-like table of contents in JavaScript Notion-like table of contents in JavaScript Long web pages benefit from having a table...
6 months ago
59
6 months ago
Notion-like table of contents in JavaScript Long web pages benefit from having a table of contents. Especially technical, reference documentation. As a reader you want a way to quickly navigate to a specific part of the documentation. This article describes how I...
Krzysztof Kowalczyk...
Porting a medium-sized Vue application to Svelte 5 Porting a medium-sized Vue application to Svelte 5 The short version: porting from Vue...
8 months ago
57
8 months ago
Porting a medium-sized Vue application to Svelte 5 The short version: porting from Vue to Svelte is pretty straightforward and Svelte 5 is nice upgrade to Svelte 4. Why port? I’m working on Edna, a note taking application for developers. It started as a...
Krzysztof Kowalczyk...
Changing font size in Windows dialog in C++ How to dynamically change font size in a Windows dialog Windows’s win32 API is old and...
10 months ago
56
10 months ago
How to dynamically change font size in a Windows dialog Windows’s win32 API is old and crufty. Many things that are trivial to do in HTML are difficult in win32. One of those things is changing size of font used by your native, desktop app. I encountered this in...
Krzysztof Kowalczyk...
Man vs. AI: optimizing JavaScript (Claude, Cursor) How AI beat me at code optimization game. When I started writing this article I did not...
5 months ago
52
5 months ago
How AI beat me at code optimization game. When I started writing this article I did not expect AI to beat me at optimizing JavaScript code. But it did. I’m really passionate about optimizing JavaScript. Some say it’s a mental illness but I like my code to go balls to...
Krzysztof Kowalczyk...
Lessons learned from 15 years of SumatraPDF, an open source Windows app I released first version of SumatraPDF in 2006. That’s 15 years ago which seems like a good time for...
over a year ago
20
over a year ago
I released first version of SumatraPDF in 2006. That’s 15 years ago which seems like a good time for a retrospective. The app SumatraPDF is a multi-format (PDF, ePub, Mobi, comic book, DjVu, XPS, CHM) viewer for Windows and currently looks like this: The...
Krzysztof Kowalczyk...
57 MicroConf videos for self-funded software businesses MicroConf is a conference for small/indie/self-funded software businesses. Many of their talks are...
over a year ago
18
over a year ago
MicroConf is a conference for small/indie/self-funded software businesses. Many of their talks are available on Vimeo but not well indexed. They have a better index (and another here) on their website, but also not great. This is a list of videos and a bit of info about each...
Krzysztof Kowalczyk...
@levelsio and survivorship bias Pieter Levels is a prolific maker of software. He’s also very successful maker of software: he’s...
over a year ago
17
over a year ago
Pieter Levels is a prolific maker of software. He’s also very successful maker of software: he’s close to making $1.5 million a year from his business, almost all of it profit. Almost all of it is his profit since for most of the time he was a sole developer / marketer / copy...
Krzysztof Kowalczyk...
Guide to predefined macros in C++ compilers (gcc, clang, msvc etc.) When writing portable C++ code you need to write conditional code that depends on compiler used or...
over a year ago
16
over a year ago
When writing portable C++ code you need to write conditional code that depends on compiler used or the OS for which the code is written. Here’s a typical case: #if defined (_MSC_VER) // code specific to Visual Studio compiler #endif To perform those checks you need to check...
Krzysztof Kowalczyk...
Advanced web spidering with Puppeteer Puppeteer is a node.js library that makes it easy to do advanced web scraping and spidering. Older...
over a year ago
15
over a year ago
Puppeteer is a node.js library that makes it easy to do advanced web scraping and spidering. Older generation of web scraping and spidering tools would grab and analyze HTML pages as returned by a web server. It doesn’t work well anymore because less and less website are static...
Krzysztof Kowalczyk...
How I implemented Oembed Proxy for GitHub Why Oembed Proxy for GitHub I’m writing a programming book Essential Go in Notion and I...
over a year ago
15
over a year ago
Why Oembed Proxy for GitHub I’m writing a programming book Essential Go in Notion and I need to include code snippets. Notion has support for code blocks but it’s not good enough for my use case. I want to make sure the code compiles so I write small programs and...
Krzysztof Kowalczyk...
Lessons learned porting 50k loc from Java to Go I was contracted to port a large Java code base to Go. The code in question is a Java client for...
over a year ago
15
over a year ago
I was contracted to port a large Java code base to Go. The code in question is a Java client for RavenDB, a NoSQL JSON document database. Code with tests was around 50 thousand lines. The result of the port is a Go client. This article describes what I’ve learn in the...
Krzysztof Kowalczyk...
Trade offs in designing versatile log format This article shows that when designing software even seemingly simple things are complicated and...
over a year ago
15
over a year ago
This article shows that when designing software even seemingly simple things are complicated and trade offs abound. I wanted to log events to a file. I had several requirements for my design: it should be simple and therefore easy to implement it should be human-readable it...
Krzysztof Kowalczyk...
Powering a blog with Notion and Netlify The last iteration of this blog was a Go program running on Digital Ocean’s cheapest VM...
over a year ago
14
over a year ago
The last iteration of this blog was a Go program running on Digital Ocean’s cheapest VM ($5/month). Recently I’ve made 2 big changes: I converted it to a static site hosted on Netlify I used Notion for writing the posts instead of writing markdown files in a text editor Moving to...
Krzysztof Kowalczyk...
Persisted Svelte store using IndexedDB I’m working on notepad2 for web and I need a history of opened files that persists across browser...
a year ago
14
a year ago
I’m working on notepad2 for web and I need a history of opened files that persists across browser session. Since I’m using Svelte, having it available as a store makes sense. This article describes how to implement a Svelte store whose values are persisted in IndexedDB. What is...
Krzysztof Kowalczyk...
Extreme #include discipline for C++ code C++ takes long to compile There is more than one reason for it but one of the reasons is excessive...
over a year ago
14
over a year ago
C++ takes long to compile There is more than one reason for it but one of the reasons is excessive re-parsing of the same .h header files. In SumatraPDF I’m using an extreme #include discipline to keep compilation times in check. The rule is simple: a .h file cannot #include...
Krzysztof Kowalczyk...
Solo founders with profitable businesses, collected stories People sometimes wonder: can I have a successful business as a single founder? The answer is:...
over a year ago
14
over a year ago
People sometimes wonder: can I have a successful business as a single founder? The answer is: yes. This is a collection of solo-preneur success stories (with occasional 2 people bands). I only include businesses generating significant revenues. In this context it’s around $5k/mo...
Krzysztof Kowalczyk...
The things we do to ship desktop software I wrote a small utility for Windows. It indexes a hard-drive and allows to find a file by name in...
over a year ago
13
over a year ago
I wrote a small utility for Windows. It indexes a hard-drive and allows to find a file by name in under a second. It might surprise you that I spent more time on things that are not related to core functionality. Let’s call it a tax of shipping desktop software. Here are some of...
Krzysztof Kowalczyk...
Optimizing JavaScript by using arrays instead of objects Best optimizations are achievied by thinking about a problem holistically. In this article I...
over a year ago
13
over a year ago
Best optimizations are achievied by thinking about a problem holistically. In this article I describe an optimization that uses arrays instead of classes while providing a class API for accessing data. Imagine you’re building a web-based note taking application. It uses modern,...
Krzysztof Kowalczyk...
Analyzing browserify bundles to minimize JavaScript bundle size When building web apps, it’s important to keep the size of JavaScript code delivered to the browser...
over a year ago
13
over a year ago
When building web apps, it’s important to keep the size of JavaScript code delivered to the browser as small as possible. I write in ES6 or TypeScript then use browserify to combine all JavaScript code into a single bundle file. For production builds I use uglify to make the...
Krzysztof Kowalczyk...
Go package for better guid generation The need to generate a globally unique identifier comes up often. The way described in RFC 4122 is...
over a year ago
13
over a year ago
The need to generate a globally unique identifier comes up often. The way described in RFC 4122 is popular but it can be done better. I wrote betterguid Go package that does it better. Unique id generated by this package: is a 20 character string, safe to include in urls (no need...
Krzysztof Kowalczyk...
SumatraPDF 2.5.2 released We, the SumatraPDF developers have released a version 2.5.2 of Sumatra, a PDF and ebook reader for...
over a year ago
13
over a year ago
We, the SumatraPDF developers have released a version 2.5.2 of Sumatra, a PDF and ebook reader for Windows. Changes in this release: 2 page view for ebooks new keybindings: Ctrl+PgDn, Ctrl+Right : go to next page Ctrl+PgUp, Ctrl+Left : go to previous page 10x faster ebook...
Krzysztof Kowalczyk...
Advanced markdown processing in Go Using gomarkdown/markdown library This article describes an advanced markdown processing...
a year ago
13
a year ago
Using gomarkdown/markdown library This article describes an advanced markdown processing in Go using gomarkdown/markdown library. All the code examples are available at https://github.com/gomarkdown/markdown/tree/master/examples Basics first Here’s a good...
Krzysztof Kowalczyk...
SumatraPDF 3.0 released We, the SumatraPDF developers have released a version 3.0 of Sumatra, a multi-format reader (PDF,...
over a year ago
13
over a year ago
We, the SumatraPDF developers have released a version 3.0 of Sumatra, a multi-format reader (PDF, epub and mobi ebooks, comic books, etc.) for Windows. You can download it from official SumatraPDF website The biggest change in this version is addition of tabs, contributed by...
Krzysztof Kowalczyk...
How I reverse engineered Notion API Notion is a great tool for writing but the content is trapped inside the web app. The company is...
over a year ago
13
over a year ago
Notion is a great tool for writing but the content is trapped inside the web app. The company is working on an official API but I’m impatient. This article describes how I reverse engineered their API and created a Go library notionapi. It all began with a failure. My...
Krzysztof Kowalczyk...
Ideas for replit bounties Apparently replit asks all Pro users about their thoughts. As it happens, I have a lot of thoughts...
a year ago
13
a year ago
Apparently replit asks all Pro users about their thoughts. As it happens, I have a lot of thoughts about how to improve Replit bounties. Lower transaction costs Currently the process is: I post a bounty one or more people apply I select an applicant they do the work I...
Krzysztof Kowalczyk...
Find programming work by increasing luck surface area Antonio asked on HN: How do I earn a small amount of money to sustain myself as a developer? I wrote...
over a year ago
13
over a year ago
Antonio asked on HN: How do I earn a small amount of money to sustain myself as a developer? I wrote a response centered around increasing luck surface area. This essay expands on it because I’ve seen this a few times now: good developers asking how to find work while botching...
Krzysztof Kowalczyk...
Tutorial for github.com/kjk/flex Go package (implementation of CSS flexbox algorithm) Package github.com/kjk/flex implements CSS flexbox layout algorithm in Go. It’s a pure Go port of...
over a year ago
12
over a year ago
Package github.com/kjk/flex implements CSS flexbox layout algorithm in Go. It’s a pure Go port of Facebook’s Yoga C library. High-level API overview Despite implementing CSS flexbox spec, it isn’t tied to CSS/HTML in any way. Yoga, for example, can be integrated with...
Krzysztof Kowalczyk...
How I use Roam Research I take lots of notes and I’m always looking for that perfect note taking app. Because I take a lot...
over a year ago
12
over a year ago
I take lots of notes and I’m always looking for that perfect note taking app. Because I take a lot of notes, mobile-first note taking apps (e.g. Google’s Keep) are of no interest to me. To me most important thing is: lowest possible friction in adding new notes fast way of...
Krzysztof Kowalczyk...
How I implemented wc in the browser in 3 days Building wc in the browser From time to time I like to run wc -l on my source code to...
a year ago
11
a year ago
Building wc in the browser From time to time I like to run wc -l on my source code to see how much code I wrote. For those not in the know: wc -l shows number of lines in files. Actually, what I have to do is more like find -name "*.go" | xargs wc -l because wc isn’t...
Krzysztof Kowalczyk...
Tip for per-test verbose logging in Go One way to narrow down a problem when debugging a test is to add logging with e.g. fmt.Printf(). The...
over a year ago
10
over a year ago
One way to narrow down a problem when debugging a test is to add logging with e.g. fmt.Printf(). The problem with this approach is lack of selectivity: imagine you have 100 tests and only 1 test fails. For debugging the issue you only need to see logs when executing that 1 test...