MoreRSS

site iconThe Practical DeveloperModify

A constructive and inclusive social network for software developers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of The Practical Developer

I've Been Recording Coding Tutorials for 10 Years — Here's My Comparison of Every macOS Screen Zoom & Annotation Tool (2026)

2026-03-13 15:34:53

If you record screencasts, tutorials, or do live presentations on macOS, you've probably hit the same wall I did: how do I zoom into my screen in a way that actually shows up in the recording?

I've been producing coding tutorials for about 10 years now. Hundreds of chapters, thousands of hours of screen recording. Over that time, I've tried pretty much every tool in this space — some were great, some were expensive disappointments, and one quietly solved the problem I didn't think had a clean solution.

Here's what I found.

The Core Problem

macOS has a built-in zoom feature (Accessibility → Zoom). It works fine for personal use, but there's a catch: it doesn't show up in screen recordings. Your OBS or QuickTime capture just records the un-zoomed screen. So if you zoom in during a tutorial to highlight a line of code, your viewers see... nothing.

This is the fundamental gap that every tool below tries to address — in very different ways.

The Tools I've Used

Screen Studio ($89, one-time)

Screen Studio is probably the most polished screen recorder on macOS right now. It automatically adds zoom effects, cursor highlighting, and smooth animations — but here's the thing: it's all post-production.

You record your screen, then Screen Studio applies auto-zoom based on where your cursor moves and clicks. The results look fantastic. Genuinely beautiful output.

The problem for me: Every click triggers a zoom. When I'm coding and clicking around the IDE constantly, the video becomes a nauseating zoom-fest. You can manually adjust each zoom in the timeline, but that's exactly the kind of post-editing I'm trying to avoid when I have 40 chapters to record.

Best for: People making polished product demos or marketing videos where you have time to fine-tune the output. Not great for high-volume tutorial production.

Presentify ($14.99, one-time)

Presentify is the closest direct competitor in this space. It does cursor highlighting and screen annotations in real-time, which is exactly the right approach for live recording.

Its zoom feature works more like a magnifying glass — it enlarges the area around your cursor rather than zooming the entire screen. For some use cases that's fine, but when I'm trying to zoom into a specific code block and keep it there while I explain it, the magnifier approach feels limited.

The annotation tools are solid though. Drawing on screen, highlighting — it does those well.

Best for: Presenters who mainly need cursor visibility and basic annotations. If you don't need true screen zoom, this might be all you need.

FocuSee (Subscription)

Similar concept to Screen Studio — automatic zoom and focus effects applied after recording. It adds cursor highlighting and zoom animations based on your mouse movements.

Same fundamental issue: it's post-production. You don't control when zoom happens during recording. The auto-detection is decent but not perfect, and fixing it means more editing time.

Also, subscription pricing for a recording tool feels rough when alternatives exist.

Best for: Windows users who want Screen Studio-style output (FocuSee is cross-platform). The auto-zoom quality is reasonable.

DemoPro (Free)

DemoPro is straightforward — it lets you draw on your screen during presentations. Lines, shapes, arrows. No zoom functionality at all.

I used it for a while just for the drawing capability, paired with other tools for zoom. Works fine for what it does, but it only solves one piece of the puzzle.

Best for: Quick screen annotations during meetings or presentations where you don't need zoom.

ZoomIt (Free, Windows only)

I have to mention ZoomIt because it's genuinely the gold standard — on Windows. Made by Microsoft's Sysinternals team, it gives you real-time screen zoom, drawing, and a break timer. Simple, fast, free.

If you're on Windows, just use ZoomIt. Problem solved.

But there's no macOS version, which is why the rest of us are out here searching.

Cursor Pro ($14.99) & Mouseposé

Grouping these because they solve the same narrow problem: making your cursor more visible. Cursor Pro adds a highlight circle around your cursor. Mouseposé does the same with click effects.

Neither has zoom or drawing capabilities. They're single-purpose tools. Fine if cursor visibility is your only issue, but they don't address the zoom-and-annotate workflow.

TuringShot (Free for zoom / $2.99/yr or $9.99 lifetime)

This is the one I landed on and kept using. TuringShot does real-time screen zoom that actually appears in recordings — with any screen recorder. OBS, QuickTime, ScreenFlow, whatever you use.

The workflow: hold Ctrl+A and scroll to zoom in/out. That's it. Zoom happens when you decide, not when an algorithm guesses. The zoomed view is what gets recorded because it's rendering on the actual screen.

On top of zoom, it has:

  • Focus Highlight — a spotlight effect around your cursor (activates during zoom)
  • Screen Drawing — hold Ctrl+X and drag to draw (freehand, lines, rectangles, circles)
  • Text Memo — Ctrl+Q to place text on screen with customizable font/size/color

The drawing works while zoomed in, which was a dealbreaker with other tools. With Screen Studio and FocuSee, drawing would trigger unwanted auto-zooms. Here, zoom and drawing are independent.

Best for: Anyone who records tutorials, screencasts, or does live coding presentations and wants real-time zoom + annotation without post-editing. The price is hard to argue with — zoom is literally free.

Comparison Table

Feature TuringShot Screen Studio Presentify FocuSee DemoPro
Live Zoom ✅ Ctrl+A+scroll ❌ Post only ⚠️ Magnifier ❌ Post only
Focus Highlight ✅ Auto ✅ Auto
Screen Drawing ✅ Ctrl+X+drag
Text Memo ✅ Ctrl+Q
Real-time (no post-edit)
Works with any recorder N/A (built-in) N/A (built-in)
Price Free–$9.99 $89 $14.99 Subscription Free
macOS
Windows

My Current Workflow

After years of experimentation, here's what I settled on:

  1. During recording: Zoom in with Ctrl+A+scroll when I want to highlight something. Draw with Ctrl+X+drag when I need to circle or underline. Drop text with Ctrl+Q when I need to show a note on screen.
  2. After recording: Run the video through Filmora's silence removal to cut dead air and pauses.
  3. Done. No zoom editing. No annotation editing. No timeline tweaking.

For someone recording 30-40 tutorial chapters at a time, this saves hours per batch.

Bottom Line

There's no single "best" tool here — it depends on what you need:

  • Beautiful, polished demos? → Screen Studio
  • Quick cursor visibility? → Presentify or Cursor Pro
  • Windows real-time zoom? → ZoomIt
  • Real-time zoom + drawing + recording on macOS? → TuringShot
  • Just drawing on screen? → DemoPro

If you're in the "I need to record lots of tutorials without spending hours on post-editing" camp like me, TuringShot has been the answer. But I genuinely appreciate what Screen Studio does for people who have time to polish their output — the results are gorgeous.

🔗 TuringShot Website | App Store

Why I stopped using Tiptap and built my own HTML editor

2026-03-13 15:29:00

Building a custom HTML editor for a React blog instead of using Tiptap

While building my personal blog, I had to choose a rich-text editor for writing articles.

At first I experimented with Tiptap, which is a very popular solution for rich text editing in React applications. It’s powerful and flexible, but after working with it for a while I realized it introduced more complexity than I actually needed.

My blog uses a custom content pipeline and a controlled HTML output, so debugging and controlling the generated markup became harder than expected.

Eventually I decided to take a different approach and build my own lightweight HTML editor.

The goals were simple:

  • full control over the generated HTML
  • predictable formatting output
  • minimal dependencies
  • easier debugging

Building a custom editor turned out to be a very interesting challenge, especially when dealing with formatting logic, preview rendering and content sanitization.

I wrote a detailed explanation on my
technical web development blog.

You can read the full article here:
building a custom HTML editor

If you’re building your own tools or experimenting with custom blog systems,
I’d be curious to hear what approach you chose !

Ingeniería S&OP III: El Fin de Excel (Programación Lineal para Supply Planning)

2026-03-13 15:25:29

"Siempre queremos X semanas de cobertura." Esta frase, repetida como mantra en todas las reuniones de S&OP del planeta, es financieramente tóxica.

¿Por qué? Porque es una regla fija aplicada a un sistema dinámico. Si tu demanda en enero es 200 unidades y en julio es 20, te estás obligando a mantener 800 y 80 unidades respectivamente "por si acaso". En enero te queda corto. En julio inmovilizas capital sin motivo.

La alternativa no es intuición más sofisticada. Es matemáticas.

Resumen Ejecutivo: En este capítulo, conectamos el forecast probabilístico del Capítulo 2 con un motor de Programación Lineal (PuLP) que calcula el plan de producción exacto que minimiza el coste total (producción + almacenamiento) respetando la restricción de Safety Stock. Pasamos de la predicción pasiva a la prescripción activa.

Del Forecast a la Decisión: Arquitectura

En el Capítulo 1 limpiamos la señal. En el Capítulo 2 predijimos la demanda. Ahora damos el paso que Excel no puede dar: optimizar.

Nuestro pipeline en GitHub se conecta a Supabase, lee la tabla demand_forecasts (el futuro que predijimos), y genera una nueva tabla supply_plans. El sistema ha pasado de descriptivo (¿qué pasó?) a predictivo (¿qué pasará?) y ahora a prescriptivo (¿qué debo hacer?).

Esto es Investigación Operativa. La misma disciplina que optimiza rutas aéreas, logística militar y cadenas de suministro globales. Y la ejecutamos con 50 líneas de Python.

Las Matemáticas del Negocio

No vamos a esconder las ecuaciones. Son el corazón de la decisión. Aquí está el fragmento central de nuestra clase SupplyOptimizer:

# Función Objetivo: Minimizar coste total
problem += pulp.lpSum(
    production_cost * production[t] + holding_cost * inventory[t]
    for t in range(T)
), "Total_Cost"

# Restricción: Balance de Inventario (Ley de Conservación de Masas)
for t in range(T):
    prev_inv = initial_inventory if t == 0 else inventory[t - 1]
    problem += (
        inventory[t] == prev_inv + production[t] - demand[t],
        f"Balance_t{t}"
    )

# Restricción: Safety Stock (Política de Riesgo)
for t in range(T):
    problem += (
        inventory[t] >= safety_stock,
        f"SafetyStock_t{t}"
    )

Tres decisiones de ingeniería que merecen explicación:

La Función Objetivo no busca "tener mucho stock" ni "producir mucho". Busca el mínimo coste financiero: el equilibrio entre fabricar (caro) y almacenar (caro también). El solver encuentra automáticamente el punto exacto donde el coste combinado es mínimo.

El Balance de Masas es una restricción física: no puedes vender lo que no tienes. El inventario de hoy es el de ayer, más lo que fabricas hoy, menos lo que vendes. No hay magia. Las ecuaciones prohíben las trampas.

El Safety Stock es la política de riesgo: nunca permitas que el inventario baje por debajo de un mínimo de seguridad. En nuestro caso, 1,5 meses de demanda media. Esto lo calcula el sistema, no una hoja de cálculo con un número puesto a dedo.

El Plan Maestro: De Algoritmo a Decisión de Negocio

Plan Maestro de Producción optimizado con PuLP: producción, inventario y Safety Stock por mes
Esto es lo que el Director de Operaciones necesita ver. El algoritmo no fabrica uniformemente: si detecta un pico enorme de demanda en un periodo, decide "pre-construir" (pre-build) inventario en los meses anteriores para aplanar la carga de producción. Si el Holding Cost es alto, mantiene el almacén vacío y fabrica Just-in-Time. Excel no hace esto solo; las matemáticas sí.

El resultado de nuestro solver con los datos de prueba:

  • Coste de producción: 1.680 EUR
  • Coste de almacenamiento: 540 EUR
  • Coste total optimizado: 2.220 EUR

Este número no es una estimación. Es el mínimo global demostrable dadas las restricciones. Si alguien propone un plan más barato con los mismos parámetros, está violando alguna restricción.

Open Kitchen: Juega con el Solver

Desconfío de las teorías que no se pueden poner en práctica. Por eso, he preparado un Google Colab donde puedes ejecutar el optimizador sobre un snapshot de nuestros datos reales.

El experimento más revelador: cambia el holding_cost a un valor altísimo (por ejemplo, 50 EUR/unidad). Observa cómo el algoritmo, automáticamente, decide fabricar Just-in-Time y mantener el almacén prácticamente vacío. Luego baja el coste de producción y mira cómo prefiere fabricar de golpe y almacenar. Las matemáticas se adaptan. Las reglas fijas de Excel, no.

📎 Abrir el Google Colab Interactivo

Modifica los costes, las restricciones de capacidad, el Safety Stock. Haz ingeniería, no fe.

La cadena completa: De Datos a Decisiones

Con este tercer capítulo, hemos construido un sistema S&OP end-to-end que va desde el CSV sucio del ERP hasta un plan de producción óptimo:

arquitectura

Siguiente Paso: Escalando a Enterprise

Ya tenemos el plan perfecto en nuestra base de datos. Pero solo para un producto. ¿Qué pasa cuando metes 3 SKUs que comparten la misma fábrica?

En el Capítulo 4 rompemos el MVP: inyectamos datos multi-producto con perfiles radicalmente distintos, paralelizamos el forecasting con MLOps, y construimos un modelo unificado de Programación Lineal donde los productos compiten matemáticamente por la capacidad de producción compartida.

La diferencia entre un Director de Operaciones que planifica y uno que optimiza es una función objetivo entre su intuición y la realidad.

Quantifying synergistic mutual information

2026-03-13 15:20:06

{{ $json.postContent }}

Stop blindly replacing `enum` with `as const`

2026-03-13 15:18:46

You’ve probably seen many posts suggesting that we should replace TypeScript enum with as const objects because of benefits like:

  • better tree-shaking
  • smaller bundle size
  • less runtime code

That advice is not entirely wrong, but it is often oversimplified.

The real question is not “Should we stop using enums?”
The better question is:

Do we actually understand what TypeScript generates behind the scenes, and what trade-offs we are making?

The key idea: reverse mapping

For numeric enums, TypeScript generates extra runtime code.

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

This is transpiled to JavaScript roughly like this:

var Direction;
(function (Direction) {
  Direction[Direction["Up"] = 0] = "Up";
  Direction[Direction["Down"] = 1] = "Down";
  Direction[Direction["Left"] = 2] = "Left";
  Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));

At first glance, that looks weird.
But here is what is happening:

  1. TypeScript creates an IIFE (Immediately Invoked Function Expression).
  2. It assigns Direction["Up"] = 0.
  3. That assignment returns 0, so TypeScript also sets Direction[0] = "Up".

So at runtime, we get an object like this:

{
  Up: 0,
  Down: 1,
  Left: 2,
  Right: 3,
  0: "Up",
  1: "Down",
  2: "Left",
  3: "Right"
}

This is called reverse mapping.

That means:

Direction.Up // 0
Direction[0] // "Up"

Why some developers prefer as const

Now compare that with:

const DirectionConst = {
  Up: "Up",
  Down: "Down",
  Left: "Left",
  Right: "Right",
} as const;

This is just a plain JavaScript object.
No IIFE.
No reverse mapping.
No extra enum runtime emit.

That is why many developers say as const can be better for:

  • frontend apps
  • config objects
  • route names
  • statuses
  • action types
  • other JS-first patterns

But does that mean enum is bad?

Not at all.

The real issue is that many people blindly replace enums without understanding the use case.

Because not all enums are the same:

  • numeric enums generate reverse mapping
  • string enums do not generate reverse mapping
  • const enum has a different trade-off again
  • as const is not a 1:1 replacement for every enum use case

The important takeaway

We should not blindly replace enum with as const just because it is trending.

Instead, we should ask:

  • Do we need reverse mapping?
  • Do we need a runtime enum object?
  • Are we using numeric enums or string enums?
  • Is this app code, library code, or protocol/compiler-style code?
  • Are we optimizing for explicitness, bundle size, or JS simplicity?

Final thought

as const is a great pattern.
But enum is not automatically wrong.

The real senior move is not to follow slogans like:

“Stop using enums.”

The real senior move is to understand how TypeScript works behind the scenes and choose the right tool for the right use case.

S&OP Engineering III: The End of Excel (Linear Programming for Supply Planning)

2026-03-13 15:16:12

"We always want 4 weeks of coverage." This phrase, repeated like a mantra in every S&OP meeting on the planet, is financially toxic.

Why? Because it's a fixed rule applied to a dynamic system. If your demand in January is 200 units and in July is 20, you're forcing yourself to maintain 800 and 80 units respectively "just in case." January falls short. July immobilizes capital for no reason.

The alternative isn't more sophisticated intuition. It's mathematics.

Executive Summary: In this chapter, we connect the probabilistic forecast from Chapter 2 with a Linear Programming engine (PuLP) that calculates the exact production plan minimizing total cost (production + storage) while respecting Safety Stock constraints. We move from passive prediction to active prescription.

From Forecast to Decision: Architecture

In Chapter 1 we cleaned the signal. In Chapter 2 we predicted demand. Now we take the step Excel can't: optimize.

Our pipeline on GitHub connects to Supabase, reads the demand_forecasts table (the future we predicted), and generates a new supply_plans table. The system has evolved from descriptive (what happened?) to predictive (what will happen?) and now to prescriptive (what should I do?).

This is Operations Research. The same discipline that optimizes airline routes, military logistics, and global supply chains. And we run it with 50 lines of Python.

The Mathematics of Business

We're not going to hide the equations. They're the heart of the decision. Here's the core fragment from our SupplyOptimizer class:

# Objective Function: Minimize total cost
problem += pulp.lpSum(
    production_cost * production[t] + holding_cost * inventory[t]
    for t in range(T)
), "Total_Cost"

# Constraint: Inventory Balance (Conservation of Mass)
for t in range(T):
    prev_inv = initial_inventory if t == 0 else inventory[t - 1]
    problem += (
        inventory[t] == prev_inv + production[t] - demand[t],
        f"Balance_t{t}"
    )

# Constraint: Safety Stock (Risk Policy)
for t in range(T):
    problem += (
        inventory[t] >= safety_stock,
        f"SafetyStock_t{t}"
    )

Three engineering decisions worth explaining:

The Objective Function doesn't seek "lots of stock" or "high production." It seeks the minimum financial cost: the equilibrium between manufacturing (expensive) and storing (also expensive). The solver automatically finds the exact point where the combined cost is minimal.

The Mass Balance is a physical constraint: you can't sell what you don't have. Today's inventory equals yesterday's, plus what you produce today, minus what you sell. No magic. The equations forbid cheating.

The Safety Stock is the risk policy: never let inventory drop below a safety minimum. In our case, 1.5 months of average demand. The system calculates this, not a spreadsheet with a number pulled from thin air.

The Master Plan: From Algorithm to Business Decision

Master Production Schedule optimized with PuLP: production, inventory, and Safety Stock by month
This is what the Operations Director needs to see. The algorithm doesn't produce uniformly: if it detects a massive demand spike in one period, it decides to "pre-build" inventory in preceding months to flatten the production load. If Holding Cost is high, it keeps the warehouse empty and manufactures Just-in-Time. Excel doesn't do this on its own; mathematics does.

The result from our solver with test data:

  • Production cost: €1,680
  • Storage cost: €540
  • Total optimized cost: €2,220

This number is not an estimate. It's the provable global minimum given the constraints. If someone proposes a cheaper plan with the same parameters, they're violating a constraint.

Open Kitchen: Play with the Solver

I distrust theories that can't be put into practice. That's why I've prepared a Google Colab where you can run the optimizer on a snapshot of our real data.

The most revealing experiment: change holding_cost to an extremely high value (e.g., €50/unit). Watch how the algorithm automatically decides to manufacture Just-in-Time and keep the warehouse practically empty. Then lower the production cost and watch it prefer to produce in bulk and store. Mathematics adapts. Excel's fixed rules don't.

📎 Open the Interactive Google Colab

Modify the costs, capacity constraints, Safety Stock. Do engineering, not faith.

The Complete Chain: From Data to Decisions

With this third chapter, we've built an end-to-end S&OP system that goes from a dirty ERP CSV to an optimal production plan:

architecture

Next Step: Scaling to Enterprise

We now have the perfect plan in our database. But only for one product. What happens when you add 3 SKUs sharing the same factory?

In Chapter 4 we break the MVP: we inject multi-product data with radically different profiles, parallelize the forecasting with MLOps, and build a unified Linear Programming model where products compete mathematically for shared production capacity.

The difference between an Operations Director who plans and one who optimizes is an objective function between their intuition and reality.