Hi 👋🏻, I'm Stefan

I care personally about great developer experiences and write about Monorepos, TypeScript, Frontend Architecture, DevOps and SRE.
TECHNOLOGIES I WORK WITH
*[Rust] when I feel like suffering
THIS IS MY JAM
{
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"cache": true
},
"test": {
"cache": true,
"inputs": ["default", "^production"]
}
},
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": ["default", "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?"]
},
"plugins": [
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
}
]
}
import * as ts from 'typescript';
function createTransformer(): ts.TransformerFactory<ts.SourceFile> {
return (context) => {
return (sourceFile) => {
const visitor = (node: ts.Node): ts.Node => {
if (ts.isCallExpression(node)) {
return ts.factory.createCallExpression(
node.expression,
node.typeArguments,
node.arguments
);
}
return ts.visitEachChild(node, visitor, context);
};
return ts.visitNode(sourceFile, visitor);
};
};
}
trigger:
branches:
include: [main, develop]
pool:
vmImage: 'ubuntu-latest'
jobs:
- job: BuildAndTest
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
- script: npm ci
displayName: 'Install dependencies'
- script: npx nx run-many --target=build --all --parallel=4
displayName: 'Build all projects'
- script: npx nx run-many --target=test --all --parallel=3 --code-coverage
displayName: 'Run tests with coverage'
@Injectable({ providedIn: 'root' })
export class DataService {
private readonly http = inject(HttpClient);
private readonly apiUrl = 'https://api.powerbi.com';
readonly getData$ = this.http.get(this.apiUrl).pipe(
retry(3),
shareReplay(1),
catchError(this.handleError)
);
readonly searchResults$ = this.searchTerm$.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(term => this.search(term))
);
}
(Same year VS Code was released)
ALL ARTICLES

Creating a TypeScript ES Lint Plugin
Learn how to create a custom typescript-eslint rule for your TypeScript project. If you ever wanted to enforce a certain pattern in your codebase, this article is for you. I will show you how to create a custom rule based on a real-world example.

Incremental Builds with Nx
If you have a monorepo with multiple projects and libraries, you might run into the problem of long build times. This article explains how incremental builds with Nx work under the hood and we will explore Nx's internal codebase to understand how it works.

Refactoring at Scale
Refactoring a large codebase can be a daunting task. In this article, we will explore some strategies for refactoring at scale using the TypeScript Compiler API to programmatically analyze and transform TypeScript code.

Module Boundaries with Nx
Module boundaries are a great way to enforce architectural rules in your monorepo and manage dependencies. They allow you to define strict boundaries, which can be used to enforce architectural rules and prevent accidental dependencies between modules.