I’m a “full stack” software engineer.
I previously worked as the CTO at Sessions and Webmarc.
You can read more about me here.
Contact me
Looking for a fresh perspective on the tech industry? Check out my blog where I write about some more in-depth topics.
My experience
Skilled in some
stuff
My projects
kubernate
If you're looking for a way to generate valid Kubernetes YAML, you might want to consider using an imperative, type-safe approach. Instead of using a templating language like Helm or writing YAML files manually, you can write actual code that generates the YAML for you. This approach is a specific implementation of Infrastructure as Code, with a focus solely on Kubernetes.
While generic IaC tools like Terraform, Pulumi, and AWS CDK can certainly be used to deploy Kubernetes resources, there are some potential drawbacks to consider. One of the biggest risks is that these tools might not be optimized for Kubernetes, which can lead to performance and reliability issues. For example, when using a generic tool to deploy Kubernetes resources, you might run into synchronization issues sooner or later. This is because the generic tool will try to replicate the state of Kubernetes in external systems, which can lead to synchronization issues.
On the other hand, by using an approach that is tailored specifically to Kubernetes, you can avoid these potential issues and ensure that your deployments are as reliable and performant as possible. With an imperative, type-safe approach, you can write code that generates the exact Kubernetes resources that you need, with all the necessary metadata and configuration options. This approach can also help you catch errors earlier in the development process, since you're writing code instead of manually editing YAML files.
Overall, if you're looking for a more efficient and reliable way to generate Kubernetes YAML, an imperative, type-safe approach is definitely worth considering.
TypeScript
96.2%
Handlebars
2.7%
JavaScript
1.1%
react-directive-attributes
This project aims to provide React developers with a similar functionality as Angular's attribute directive. With this package, users can create wrapper components and bind them to attributes, making it easier than ever to add behavior to a component from the markup.
React is a popular and widely-used JavaScript library for building user interfaces. React's component-based architecture makes it easy to create reusable and modular UI elements. However, one downside of React is that it can be challenging to add behavior to components from the markup. With the help of this package, developers can easily add behavior to their components without having to write additional code.
In summary, this project provides React developers with a more straightforward way to add behavior to components from the markup, similar to Angular's attribute directive. This package makes it easier than ever to create reusable and modular UI elements with added functionality.
TypeScript
100%
kmconf
JS/TS projects have complex configurations, making management challenging. This project has three components: a kernel module, a user-space daemon, and a CLI.
The kernel module intercepts reads on char-devices, forwarding requests to the daemon.
The CLI enables users to create and manage projects with a single config file, creating fake config files via symlinking.
The daemon maps files to devices and uses a dedicated renderer to return text upon receiving a read request.
C
64.7%
TypeScript
32.2%
Makefile
3.2%
TJ
This is a small and clean Java Virtual Machine implemented in Typescript that can run on Node and in the browser. It implements 3 opcodes that allow it to run simple programs like "hello world". However, it can be further developed to run more complex programs.
A key motivation behind this project was to parse .class
files, which helped me gain a better understanding of the JVM and Java bytecode processing. I also gained experience in writing parsers and interpreters, which improved my overall software development skills.
In summary, this project is an excellent resource for anyone interested in learning about the JVM, its inner workings, and experimenting with its capabilities, whether they are a beginner or an experienced developer.
TypeScript
99.5%
Other
0.5%
prx-remote
I have a VM workstation on my home server, which runs Proxmox and other services. To start the VM, I created an over-engineered power button with two components: an HTTP server on Proxmox and an ESP32 MCU with a button.
The ESP32 connects to my Wi-Fi and triggers the HTTP server to boot the VM when the button is pressed. The hardware is basic and powered via USB, housed in a partially 3D-printed enclosure.
Watch it in action here.
C++
48.8%
TypeScript
36.4%
C
14.8%
typescript
I am very excited about Rust's meta-programming system. One of the most impressive features of Rust macros is that they allow for compile-time code execution with no performance penalty. This is a huge boon for developers, as it enables them to create a truly seamless programming experience.
Unfortunately, my other favorite programming language, Typescript, does not support compile-time code execution. Although I have long admired Typescript's many strengths, the lack of support for Rust macros has always been a sticking point for me. In an effort to overcome this limitation, I have decided to create my own implementation of compile-time code execution in Typescript.
My project allows users to define their own macros using a new keyword, which I have named macro. These macros are simply normal functions that are called at compile time during transformation, as well as during checking. This means that they can be used to generate both code that will be emitted in the final output, as well as types that can be used during development by the language server to provide IntelliSense and other code actions.
In addition to implementing support for Rust macros, I have also included several other features that I have always wanted in Typescript. These include:
defer
statements: similar to Go's defer, but can be used with any statement or block, not just functions.derive
implementations for classes: works like implements
or extends
, but with the implementation generated by a macro.using
statements: similar to C#'s using for Disposable
.To help other developers get started with this fork of Typescript, I have created a set of demos, which can be found at https://github.com/laurci/ts-fork-demos. I have also developed a VS Code extension that adds syntax highlighting for the new keywords I have introduced. The extension can be found at https://github.com/laurci/ts-fork-vscode.
TypeScript
99.9%
Other
0.1%
ts-llvm
This experiment uses the features of my compiler to parse Typescript code and generate LLVM IR that gets then converted into a native binary. It is a very minimal implementation but can be expanded to support more of the Typescript AST and thus allow for more complex programs.
TypeScript
100%
proto-type
This project uses the features of my compiler to create a better RPC client/server framework using Google ProtoBuf. You can describe your messages and RPCs like normal using ProtoBuf and then use the proto!
macro to load them in. You can then use the instance returned by the macro to create a client or a server.
The proto!
macro parses the ProtoBuf you provided and extracts the needed information. It then generates code that can be used by both the client and the server to encode/decode the messages and RPCs. It also generated the types to match the ProtoBuf.
TypeScript
100%
metal
This project was built during the Bucharest Hackathon 2023 which we (me and my team Deadlock) ended up winning.
We wanted to empower users without Digital Hardware Design experience to easily build their own hardware (like accelerators, custom peripherals, high-performance signal processing, custom actuator drivers, etc) using the tools they already know.
I believe that this project can have a huge impact on the iteration speed (from software to ASIC), but also it can provide cheaper access to educational products (ex: let's say you buy an Arduino for $30. You play with the basic stuff and it gets pretty interesting. You are now ready to try some advanced projects. You want to connect to the internet. You do some research and find out about the Ethernet Shield, but quickly give up when you see it costs 2-3x more than the Arduino. With Metal, this roadblock would not exist. The shield can be just a library that you can download from GitHub and it comes with both hardware and software to use it. Now the only thing you need is the RJ45 connector that you can buy with a breakout for $5).
We used Rust’s amazing meta-programming system to extract functions annotated by the user with the #[metal::teleport] directive and convert them into hardware implementations by generating Scala code (that is later converted into Verilog using Spinal HDL). The hardware implementations are APB3 bus slaves and memory-mapped at known locations. We replace the function body with a basic copy from arguments to the locations mapped as the inputs for the APB3 slave and from the location mapped to the return value. Now everywhere the function is called, its inputs and outputs will be correctly transferred to the hardware implementation.
We compile the Rust code to the riscv32-imc target and we link it using a known memory map. We combine the generated hardware implementation with a standard RISCV 32 bits IMC softcore and we generate the bitstream. We load the generated binary (from the Rust code) into the generated block RAM and we load the final bitstream into the FPGA. Now your code runs and it interacts with the generated hardware peripherals like it would with normal memory.
Scala
97.4%
Rust
1.9%
Other
0.7%
meta-utils
This project is a collection of utilities that are used by my other macros. It uses many of the features in my compiler to provide a better developer experience for things like build configuration, logging, FS path operations, etc.
TypeScript
100%
so-loader
This project uses the features of my compiler to expose a better interface to working with FFI in Node. It uses dwarfdump to analyze the .so files and find exposed functions that follow the C-ABI calling conventions (note: your library must include the dwarf debugging information during development, you can ship a stripped binary in production). From the debug information collected, it generates the code needed to dynamically load the library and call the exposed functions, but also the types for these functions.
TypeScript
98.4%
C++
1.6%