Servoy Tutorials

Hey everyone,

This is my running list of Servoy tutorials on dotzlaw.com. I add new ones as I publish them and I keep the older ones linked here because most of the fundamentals still apply a decade later. Bookmark this post. I will keep updating it.

If you are not using the new AI Runtime Plugin (`plugins.ai`) that shipped with Servoy 2025.12, you need to read the latest articles below to see what you are missing. If you are new to Servoy, start at the bottom of the post with the Foundations section and work your way up.

I aim to publish a new tutorial every week. Check back on Sundays.


Latest Additions

**The Servoy AI Runtime Plugin Series (April 2026).** A four-part deep dive into `plugins.ai`, the Langchain4j-backed runtime that shipped with Servoy 2025.12. Read them in order.

**[Part 1: Getting Started with the Servoy AI Runtime Plugin]( Getting Started with the Servoy AI Runtime Plugin - Dotzlaw Team )**. Chat completions with OpenAI and Gemini, streaming responses, conversation memory, multimodal input (PDFs, images), and your first vector embedding with a working semantic product search that turns “spicy hot condiments” into a ranked list of actual products.

**[Part 2: Tool Calling with the AI Runtime Plugin: Agentic Servoy]( Tool Calling with the AI Runtime Plugin: Agentic Servoy - Dotzlaw Team )**. Register your existing Servoy methods as tools the LLM can call. The agent decides what to call and in what order, then executes real business logic through your QBSelect, foundset, and `databaseManager` code. Not a demo.

**[Part 3: Embedding Your Servoy Data for Semantic Search]( Embedding Your Servoy Data for Semantic Search - Dotzlaw Team )**. Move semantic search off the in-memory store and into production with PgVector. FoundSet `embedAll()` that preserves primary keys as metadata, custom metadata columns, PDF document chunking for RAG, and batch strategies for keeping embeddings in sync.

**[Part 4: Hybrid Queries with QBVectorColumn: Semantic Meets SQL]( Hybrid Queries with QBVectorColumn: Semantic Meets SQL - Dotzlaw Team )**. The payoff article. Combine semantic similarity with traditional WHERE clauses in a single Query Builder query. Products similar to “lightweight laptop for travel”, under $2,000, in stock, active, all in one database round-trip.


The Back Catalogue (Still Relevant Today)

A lot of the older stuff is just as useful today as the day I wrote it. My favourite is **The Mighty Array**. Who knew all that stuff was hiding in the humble JavaScript array?


Foundations

**[The Mighty Array]( The Mighty Array - Dotzlaw Team )**. Advanced JavaScript array functions in Servoy. The one I still get the most feedback on.

**[Coding Efficiency]( Coding Efficiency - Dotzlaw Team )**. Frameworks, conventions, and the mindset shift that makes you twice as productive.

**[Maintainable Code]( Maintainable Code - Dotzlaw Team )**. How to write code that your future self will thank you for.

**[Encapsulation]( Encapsulation - Dotzlaw Team )**. Using Servoy’s encapsulation features on forms, relations, and value lists.

**[Using Git Flow and SourceTree]( Using Git Flow and SourceTree - Dotzlaw Team )**. The Git Flow model I have used on every Servoy project for the last decade.


Object-Oriented Programming in Servoy

**[Object-Oriented Programming]( Object-Oriented Programming - Dotzlaw Team )**. The entry point for OOP in Servoy.

**[Inheritance Patterns]( Inheritance Patterns - Dotzlaw Team )**. A tour of the different ways to do inheritance.

**[Prototypal Inheritance]( Prototypal Inheritance - Dotzlaw Team )**. Prototypes in Servoy, done right.

**[Multiple Inheritance]( Multiple Inheritance - Dotzlaw Team )**. How to share behaviour across unrelated objects.

**[Parasitic Inheritance]( Parasitic Inheritance - Dotzlaw Team )**. A pattern with a strange name and a legitimate use case.

**[Decorator Design Pattern]( Decorator Design Pattern - OOP - Dotzlaw Team )**. Extending behaviour without touching the original object.

**[Factory Design Pattern]( Factory Design Pattern - OOP - Dotzlaw Team )**. Centralizing object creation.


Performance and Caching

**[Optimizing Code Performance]( Optimizing Code Performance - Dotzlaw Team )**. How to find and fix the slow parts.

**[Function Memoization]( Function Memoization - Dotzlaw Team )**. Caching return values to make repeat calls free.

**[Using an Object as a Cache]( Using an Object as a Cache - Dotzlaw Team )**. The pattern that still saves me database round-trips every week.

**[Optimized Table Shuffle]( Optimized Table Shuffle - Dotzlaw Team )**. Shuffling rows in a table view, the efficient way.


UI and Forms

**[Take Back the UI with OOP]( Take Back the UI with OOP - Dotzlaw Team )**. Toggling groups of UI elements elegantly.

**[Using an Object to Control Elements on Servoy Forms]( Using an Object to Control Elements on Servoy Forms - Dotzlaw Team )**. Treat form elements as members of a bigger object.

**[Button Magic]( Button Magic - Dotzlaw Team )**. Custom SVG CSS buttons that do not look like the 1990s.

**[Using CSS UI Components with Callbacks]( Using CSS UI Components with Callbacks - Dotzlaw Team )**. CSS components in Servoy with real event handling.

**[The Demise of the TreeView]( The Demise of the TreeView - Dotzlaw Team )**. Building a better tree with CSS and callbacks.

**[Table Tree View]( Table Tree View - Dotzlaw Team )**. A table with expandable and collapsible nodes.

**[Add Forms to Tab Panels using a Map]( Add Forms to Tab Panels using a Map - Dotzlaw Team )**. Controlling exactly where a form lands in a tab panel.

**[The New DesignTimeProperties]( The New DesignTimeProperties - Dotzlaw Team )**. The feature that changed how I build reusable form components.


Architecture and Testing

**[Event-Driven Architecture]( Event-Driven Architecture - Dotzlaw Team )**. Loosely coupled modules that do not know about each other.

**[Automated Testing]( Automated Testing - Dotzlaw Team )**. If you are still testing by clicking around, this one is for you.


If any of these articles are useful, pass them on. If you run into anything while building with Servoy, drop a reply here. I read every one.

Cheers,

Gary Dotzlaw

4 Likes

Quick update — adding a new tutorial to the list.

The modern ECMAScript parser is now the only parser in 2026.03, and the language has quietly grown up around us. This tutorial walks through what is actually available — let, const, arrow functions, template literals, destructuring, optional chaining, default parameters — when each one earns its place in Servoy code, and when the old patterns are still the right answer.

A few highlights:

  • The 2025.12 breaking change you should know about (block scoping for const and let finally works the way the spec says it should).

  • The arrow function trap at scope and form level. Named function declarations still win, and there is a real platform reason for it.

  • Template literals for multi-line SQL, with the one rule you cannot forget about parameterization and SQL injection.

  • A complete before-and-after rewrite of a real scope function, showing exactly where the modern features clean up the code and where the conventions stay the same.

The article targets Servoy 2025.09 or later for most features, with a couple of editor improvements that need 2026.03. If you maintain an LTS branch (2024.03 LTS or 2025.03 LTS), stick with classic ES5 — the article calls out where that line is.

This is the prelude to the next tutorial in the pipeline on Promises and async data APIs, which builds directly on the language features covered here. Cheers!

Quick update — next tutorial is up, and it is the Promises one I teased last week.

The async APIs that landed in Servoy 2025.06 for the database layer expanded in 2025.12 to cover every async plugin, and 2026.03 added Promise<T> JSDoc generics so the script editor finally types your .then() callbacks correctly. This tutorial walks through what to actually do with them — when async earns its place over a synchronous call, how to compose parallel queries, and how to handle errors without creating a new category of bugs.

A few highlights:

  • The dashboard speedup you cannot get any other way. Four independent queries at 200 milliseconds each is 800 milliseconds sequentially. Wrap them in Promise.all() and the function returns in 200 milliseconds. Same database work, four times less waiting. The article shows the exact pattern with destructured results.
  • The two-level error handling pattern. An outer try/catch for synchronous setup failures, and a terminating .catch() on the chain for async rejections. Skip either one and you get a different category of silently-swallowed bug. The tutorial walks through what each layer is actually catching, and why one of them on its own is not enough.
  • @return {Promise<JSDataSet>} is the line that makes async readable. Without the generic, every .then() callback comes through as Object and you lose autocomplete on the resolved value. With it, the editor knows what the chain is producing. Needs 2026.03 for full editor support, but the code itself runs fine on 2025.06.
  • The sync-is-still-correct cases. Transactions, single sequential queries, simple form CRUD on save. Async is not a universal upgrade — it is a tool for a specific shape of problem, and the article is direct about where the synchronous call is still the right answer.

The article targets Servoy 2025.06 or later for the data async APIs, 2025.12 for the full async plugin coverage, and 2026.03 for the Promise generic editor support. If you maintain an LTS branch (2024.03 LTS or 2025.03 LTS), the synchronous patterns from earlier tutorials still apply unchanged — the article calls out where the version line falls.

This builds directly on the modern JavaScript tutorial — the destructuring, arrow-function callbacks, and template literals from that one all show up here in .then() chains and Promise.all() result handling. And it sets up what is coming next: the typed Query Builder, and the AI Runtime Plugin, which returns a Promise from every chat completion and embedding call.

1 Like

Quick update. Tutorial #19 is up, and it is the typed Query Builder one I teased at the end of the Promises tutorial.

Servoy 2025.09 split the old monolithic `QBColumn` into five typed subclasses: `QBTextColumn`, `QBIntegerColumn`, `QBNumberColumn`, `QBDatetimeColumn`, and `QBMediaColumn`. The editor now knows what type each column actually is, code completion only offers the methods that make sense, and a whole category of “looked fine, blew up at runtime” QBSelect bugs gets caught at edit time. This tutorial walks through what changed, why it matters, and where to add the JSDoc generic so the typed columns work properly across function boundaries.

A few highlights:

- The bug the old API could not catch. `qbCust.columns.cust_id.upper.like(…)` on an integer PK used to compile silently and fail at runtime with a database error. In 2025.09+ the editor underlines `.upper` with a warning before you even save the file. The article shows the exact slip-of-the-finger pattern that triggers it.

- Five typed subclasses, plus one. `QBTextColumn`, `QBIntegerColumn`, `QBNumberColumn`, `QBDatetimeColumn`, `QBMediaColumn` shipped in 2025.09. `QBVectorColumn` followed in 2025.12 with the AI plugin work and is documented separately. The article spells out which methods live on which subclass and which return types you actually get back.

- The JSDoc generic that makes it all work. `/**@type {QBSelectdb:/myserver/crm_task}*/` is the line that brings the typed columns to life, especially after `foundset.getQuery()` (which returns `QBSelect` until you annotate it) and on `QBJoindb:/myserver/whatever` join variables.

- Migration is free. Every typed subclass extends `QBColumn`, so existing code keeps working without changes. The upgrade payoff is the editor warnings that surface on lines that used to be silent. Walk through your QBSelect-heavy modules once after the upgrade and you will find bugs you did not know were there.

The article targets Servoy 2025.09 or later for the typed `QBColumn` subclasses, and 2025.12 for `QBVectorColumn`. If you maintain an LTS branch on 2024.03 LTS or 2025.03 LTS, every QBSelect pattern you already use still works unchanged. You just do not get the editor help, so the runtime-only failure mode is still in play. The article calls out where the version line falls.

This builds directly on the Promises and async tutorial. Async returns and typed columns combine nicely once you start passing typed `QBSelect` references around through `.then()` chains. And it sets up what is coming next: the typed Solution Model, where the same generic-annotation pattern brings type-safe form, valuelist, and component references into the editor as well.

1 Like