Software engineering studio · Vienna

Systems that carry the load.

High-performance Node.js and Java backends, developer platforms and edge AI for services that need to stay up.

A model of thirty-four connected nodes: four large hubs carry most of the links, and small markers travel the links between them
Network study
Shipped for
ÖBBMercedes-Benz.ioJohnson & JohnsonNeu DenkerVolksmarktSpect0r

Software engineering. Three areas of focus.

Platforms and backends

APIs that hold when the timetable changes at four in the morning.

Architecture and implementation for API middleware, microservices and internal developer platforms, using Node.js, TypeScript and Java.

  • Node.js
  • TypeScript
  • Java
  • gRPC
  • GraphQL
  • Backstage

Edge AI and computer vision

Inference where the data already is.

I wrote the Node.js bindings for Hailo accelerators and Raspberry Pi camera modules, so the model runs next to the sensor and only the answer travels.

  • Hailo
  • On device
  • Embeddings
  • Camera pipelines
  • C++ bindings

Cloud and reliability

The work that keeps the pager quiet.

Kubernetes, CI/CD and observability for services in production, with profiling and migrations guided by the system’s constraints.

  • Kubernetes
  • Observability
  • CI/CD
  • Profiling
  • Migration
Selected work

Where downtime makes the news.

01 ÖBB

Ticketing for a national railway

Solution architect and technical team lead. Together with the team, we developed API middleware and high-performance applications in Node.js and Java.

tickets.oebb.at
A railjet crossing a viaduct on the Westbahn corridor, with the line's own topology drawn over the valley Westbahn corridor
Engineering notesfor ÖBB Architecture / technical leadership
Why this approach

Separate orchestration from service logic.

A layered middleware boundary gives API composition and individual microservices distinct responsibilities. Across Node.js and Java, that separation makes the request path easier to reason about, profile and evolve.

Context
Booking and payment for tickets.oebb.at, the online ticketing service of a national railway.
My role
Solution architect and technical team lead, connecting architecture decisions with the team’s implementation work.
Engineering
Performance-focused Node.js and Java applications, API middleware and clearly separated microservice layers.
02 Mercedes-Benz.io

One front door for hundreds of services

A Backstage developer portal that gives teams a place to find services.

mercedes-benz.io
A service dependency graph, a few hubs carrying most of the connections Service dependency graph
Engineering notesfor Mercedes-Benz.io Finding a service
Why this approach

Give service discovery a shared front door.

A Backstage portal makes finding a service part of the developer workflow. Teams can start with a shared catalog, then use a conversation for the questions the catalog cannot answer.

Context
Hundreds of services to navigate. Finding the right one can start with a question in Slack.
Approach
A developer portal built on Backstage provides a front door to the service landscape.
In practice
Teams have a place to look for a service before starting a conversation to find it.
03 Johnson & Johnson

Shared data, findable across a giant

Shared data is only useful when the right dataset can be found across departments.

A federated index: clustered datasets linked across group boundaries Federated index
Engineering notesfor Johnson & Johnson Across departmental boundaries
Why this approach

Treat discovery as part of sharing.

Storing a dataset does not make it useful to another department. A discovery layer has to cross the same boundaries as the people trying to find it; that is the purpose of the federated index.

Context
The right dataset can sit several departments away from the person who needs it.
Approach
Make shared data findable across those departmental boundaries.
In practice
Reach matters alongside storage: a dataset has to be findable from another department.
04 dofbot In house

A robot that grasps what it cannot see

Detection, depth and grasp run on the robot, with no cloud in the loop. The camera cannot see into the gripper’s working pocket. The final approach has to bridge that gap.

From sight to grasp.

Schematic
Reach and sight use different rangesTarget distance from the robot base, in centimetres. This taught approach verifies the target at 39 centimetres before a short guarded approach. The jaws work between 14 and 24 centimetres. The selected position is 22 centimetres. The staging point is a configured margin, not the camera's minimum depth specification.01020304045
15 cm · closerfarther · 45 cm

Finish the reach from what was seen.

The jaws work between 14 and 24 cm. The arm uses the previously observed target to finish the approach.

Inside the decisionfor dofbot Reach / sight / final approach
Why this approach

Stop. Observe. Correct. Then commit.

Navigation gets the robot close, but its tolerances are wider than the grasp pocket. Inference also takes time. The robot stops for a fresh observation, makes a small correction, and verifies the target before a short, guarded straight approach.

Constraint
The safe grasp pocket is 14–24 cm from the base. The eye-in-hand camera cannot see the target in that pocket.
Handoff
In the taught approach, verify the target while it is visible, then use odometry for the final calibrated straight segment.
Guardrails
No steering after the last verified camera observation. The collision guard must be enabled, and the blind advance is capped at 22 cm.

Read the code before you hire us.

Inside the open source

A frame’s journey.

Camera → on-device inference → a useful decision.

01 / Camera

One frame. Two useful views.

Keep a JPEG stream for people to see and a smaller pixel stream for the model to process. Each gets the detail it needs.

Light Image data
Explore picamera.js
Camera configuration · excerpt
import { builder } from '@nodify_at/picamera.js';

const camera = builder()
  .jpeg(1280, 720)
  .rgb(640, 360)
  .fps(30)
  .build();
Camera demo source

02 / Inference

Let the device do the seeing.

Prepare the image for the loaded model, then run it on the Hailo accelerator. The result comes back to the application as model output.

Prepared image Model output
Explore hailo.js
Inference call · excerpt
// Model loaded; image prepared.
// inputName comes from model metadata.

const outputs = await device.infer({
  [inputName]: resized
});
Inference demo source

03 / Decision

Seeing something is only the start.

The application turns detections into a useful response. Freshness, confidence and the rules of the task decide what happens next.

Detections Application response
Read the tracking example
Application policy · illustrative pseudocode
when a detection arrives
  if the frame is stale
    wait for a fresh observation
  if the target is uncertain
    observe again
  otherwise
    pass the target to the application

An example of the rules around a model.

Illustrative flow · Explore the steps to see where each library fits.

Small on purpose.

You work with Hasan Özdemir in Vienna, from software architecture to implementation. Nothing sits between the conversation and the commit.

Graphite illustration of an open engineering sketchbook, a pencil, a laptop and a small circuit board
Sketch to code Studio illustration
Pencil-and-watercolor illustration of a curious studio robot holding a graphite pencil
Studio companion Character study
Architectural illustration of Vienna: the Stephansdom spire above layered city rooftops
Vienna, AustriaCity study · illustration
Who replies
Hasan Özdemir
Based in
Vienna, Austria
Entity
nodify e.U.

How I like to work

  1. Start with the constraints.

    What must work, what it connects to, and what cannot change.

  2. Stay close to the code.

    Architecture and implementation belong in the same conversation.

  3. Leave the thinking visible.

    Write down the reasons, so the next person can keep building.

Studio notes 01

dofbot · Perception & control

Carry the measurement through.

The camera loses sight of the target before the gripper can reach it. In dofbot’s taught approach, the target is verified while it is still visible, then the base follows a short, guarded straight path.

The final grasp keeps the small position difference measured at that last check. It adjusts the grasp target; the base’s calibrated path stays the same.

The dofbot project
The last measured position difference carries into the grasp target. Illustrative offset · not to scale

A handoff should preserve the information the next step still needs.

Tell us what it has to carry.

Replies within one working day

Also from nodify

Dimwood

A cosy iOS game about leading small creatures home through a dark wood. Built here start to finish, which is the only brief where we were also the client.

  • Swift
  • SwiftUI
  • Metal
  • App Store
dimwood
The Dimwood title screen: the words Follow Me over a night sky, with three small creatures below