>_ DevTrendsen

Language

Home

Languages

Sections

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Security
TypeScript

How to test complex jq filters in the browser without risking leaking production data

How many times have you had to assemble a long jq expression blindly right in the terminal? This is a familiar scenario for many: you make an API request, get a wall of text a couple thousand lines long, and then repeatedly press the up arrow in the console, adding pipes, selectors, and slices. Made a mistake in one bracket — the terminal spits out an error or an empty array.

The first thought in such a situation is to open some online formatter. But if you're working with production logs, payment responses, or user personal data, pasting them into a random site from search results is not an option.

The jq development team solved this problem natively by releasing an official sandbox called playground. The source code is available on GitHub under the MIT license, and a working version is accessible at play.jqlang.org.

What it is

The project is an interactive web shell for working with jq. On the left side of the screen you paste the source JSON or pull it in via URL, you write the filter at the top, and on the right you instantly get the transformation result.

The main feature here is under the hood. All parsing and filter execution happen locally on your machine. The service does not send your JSON body to a remote server.

This was made possible by the jq-wasm port — the original C code of the utility was compiled to WebAssembly. As a result, the browser performs heavy transformations independently, without native dependencies on the operating system side.

How the sandbox is useful in practice

Unlike dozens of nameless services of dubious origin, this tool solves several applied tasks at once.

First, privacy by default. Since the processor runs inside WebAssembly directly on the client, you can safely upload dumps from internal databases, infrastructure configurations, or API dumps to the sandbox. Network requests only happen when you yourself paste an external URL to load JSON.

Second, convenient snippet sharing. When you need to show a colleague how to correctly parse a crooked response from a third-party service, just press the Share button. The server will save the filter code and generate a short link. The recipient of the link will have the calculations run locally in their browser again.

Third, a responsive interface. Thanks to the absence of network overhead for sending data back and forth, the result is recalculated on the fly as you type the filter. For debugging tricky constructs like walk(), recursive descents, or custom functions, this saves a lot of time.

Fourth, the sandbox can be deployed within your own perimeter. If your company operates in a closed segment without internet access, the project can be easily spun up locally or on an internal team server.

What's inside: architecture and stack

The sandbox is written in TypeScript using Next.js. The application structure is extremely concise:

  • Frontend on React with a code editor and jq-wasm integration.
  • PostgreSQL database, which is needed exclusively for storing shared snippets.
  • Server-side API endpoint (POST /api/jq) that executes requests on the backend through a worker pool.

An interesting detail in the source code: the server-side worker pool for /api/jq is tightly coupled to available RAM on the instance. Since WebAssembly instances in Node.js are memory-intensive, the application automatically calculates the thread limit based on the amount of RAM. For example, on an instance with 512 MB of memory, exactly 2 parallel threads will be launched, and the maximum queue will be 40 tasks.

If necessary, these parameters can be overridden via environment variables:

# Максимальное число параллельных потоков jq
JQ_POOL_MAX_THREADS=4

# Максимальный размер очереди запросов
JQ_POOL_MAX_QUEUE=80

If the queue overflows, the API honestly returns HTTP status 429 Too Many Requests, protecting the service from crashing due to Out of Memory.

How to deploy the project locally

If you don't want to use public hosting or need your own instance inside a corporate network, startup will take a couple of minutes.

You'll need Node.js version 14 or higher and Docker (for the database).

Clone the repository:

git clone https://github.com/jqlang/playground
cd playground

The fastest way for local development and testing is to run the ready-made Docker Compose, which will spin up the application along with a local PostgreSQL instance:

docker compose up

After startup, open your browser at http://localhost:3000.

To build a production version without containers, standard commands are sufficient:

npm run build
npm run start

The only required environment variable for production is DATABASE_URL with the PostgreSQL connection string. If the link generation functionality is not needed, the other settings can be left at their defaults.

Who will find it useful

The project is worth bookmarking for anyone who frequently deals with infrastructure code, logs in Kubernetes, CI/CD pipelines, or complex REST APIs.

The sandbox eliminates the need to write makeshift bash scripts just to check the syntax of a single filter line. And the ability to spin up your own instance in two commands makes it an excellent candidate for adding to the internal toolkit of a development team.

Related projects