Porting qs to Go: an honest account
I spent the weekend rewriting qs , the query-string parser bundled inside Express, used across a huge chunk of the Node ecosystem to Go language. This is what actually happened: what I picked, where my first version was wrong, how I checked that the rewrite behaves the same as the original. Why qs , why Go I wanted a library that mattered and a library I could actually finish. qs fit both: 8.9k…
In this article, the author recounts the experience of rewriting the qs query-string parser, originally written in JavaScript for the Express framework, in Go. The decision to rewrite qs in Go was driven by the desire to create a library that is widely used and has a well-defined core logic, with a goal of finishing the project within a weekend. Go was chosen as the target language due to its performance benefits compared to the Node runtime required by qs.
The author highlights the advantages of a Go port, including the ability to produce a single static binary without a runtime or external dependencies. However, this port came with challenges, such as adapting the original test suite to run in Go and ensuring compatibility with the JavaScript-to-Go bridge. The author found that scalar-into-array merges were incorrectly structured, leading to a fix that involved detecting the type of values being merged and handling them separately.
Another issue discovered was that the original tests did not account for the behavior of the depth option in qs. The author added a case to the test suite to handle this correctly, demonstrating the importance of thoroughly testing edge cases during a port.
The article also discusses the challenges of porting a library across a JSON-serialized boundary, as the serialization layer can introduce its own bugs. The author provides an example of a test that expects a JavaScript TypeError but encounters a nil value instead when crossing into JSON. This highlights the need for additional type-checking on the JavaScript side of the bridge.
Finally, the author mentions that some failures were left as documented limitations rather than forcing a fix, and one test case involving circular references is not fixable within the current architecture. The author concludes by using Go's fuzzer to test the roundtrip functionality of qs across millions of randomly generated inputs, ensuring deeper equivalence between the original and the ported library.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — it may contain errors, so check the original before relying on it.