Code-first ServiceNow: why Git, not the instance, now holds my application
Part 1 of 4 in the Code-first ServiceNow series. Building ServiceNow apps by clicking through forms works, but it is hard to review, hard to diff and hard to hand to an AI agent safely. This is the architecture I'm using instead: Coder workspaces, Node 24, the ServiceNow SDK with Fluent, Git, pull requests, ATF and gated promotion from DEV to TEST to PROD.

Part 1 of 4 in the Code-first ServiceNow series. Building ServiceNow apps by clicking through forms works, but it is hard to review, hard to diff and hard to hand to an AI agent safely. This is the architecture I'm using instead: Coder workspaces, Node 24, the ServiceNow SDK with Fluent, Git, pull requests, ATF and gated promotion from DEV to TEST to PROD.
- For scoped application metadata that is deliberately managed through the ServiceNow SDK, the Git repository is authoritative. The instance remains essential, but as a runtime and validation target rather than the only place the application exists.
- The toolchain is ordinary modern engineering: a reproducible Coder workspace, Node.js 24, the ServiceNow SDK with Fluent (a TypeScript-based language for ServiceNow metadata), Git branches, pull requests, build checks, ATF and gated promotion.
- It is a hybrid model on purpose. Existing global configuration, Flow Designer work owned by process teams, vendor applications and data fixes keep using the right native mechanism.
- ServiceNow's own SDK guidance now points the same way: Git as the source of truth, direct SDK installs for development instances, and the Application Repository for test and production.
- AI agents fit naturally into this model because their output is a reviewable diff, not a series of clicks. They get non-production access only; production always needs a human approval.
Code-first ServiceNow, part 1 of 4. Part 1: Architecture (this article) · Part 2: Workstation setup · Part 3: SDK, Fluent and Git workflow · Part 4: Governance and AI agents
For most of my time on ServiceNow, building something has meant opening the instance, finding the right form, creating a record, clicking through a builder, capturing the work in an update set and then promoting that update set onwards. It works. Thousands of teams ship that way every day. But it has costs that get more obvious the more people (and, increasingly, the more AI agents) touch the same application.
This series documents a different route that I've been putting together as a reference implementation: a code-first way of building ServiceNow scoped applications, where the application's intent lives in a Git repository and the instance becomes the place that code is deployed to and validated on. This first part covers the why, the whole toolchain end to end, and the principle that holds it together: Git is the source of truth for SDK-managed code, and ServiceNow is the runtime target.
The problem with building by clicking
The ServiceNow SDK documentation puts the problem more bluntly than I would have: apps built by clicking through Studio or forms are "hard to code-review, hard to diff, and easy to lose track of what changed". In my experience that shows up in three ways.
Review is shallow. A peer reviewing an update set is looking at a list of records and XML payloads, not a readable change. It is possible to review properly, but it is slow, so in practice a lot of review happens by clicking around the instance afterwards.
Collaboration collides. Update sets were designed to record and replay changes, not to merge concurrent work. ServiceNow's own SDLC guide notes there is no line-by-line merge for conflicting update sets, and that backing changes out one set at a time does not always return you to an exact previous state.
The instance becomes the only copy. If the real version of an application is whatever is on the development instance today, it is only as reliable as the last person who edited it. There is no clean history, no branch to throw away, and no easy way to reproduce the application elsewhere.
None of this is new. What has changed is the arrival of AI coding agents. An agent that clicks through a UI on your behalf is very hard to review. An agent that writes a small, typed diff on a branch can be reviewed exactly like any other contributor. That difference is a large part of why I've invested in this route.
What "code-first" means here
The reference implementation lives in my own practice repository (private), which describes itself as a platform for moving scoped application development "away from repetitive UI-first authoring and toward a source-driven engineering model".
In practice that means:
- application metadata such as tables, roles, ACLs, business rules, client scripts and ATF tests is written in Fluent, in
.now.tsfiles undersrc/fluent/; - server-side logic lives in real JavaScript or TypeScript modules (for example
src/server/script.ts) that Fluent files import; - the ServiceNow SDK (
@servicenow/sdk, pinned to 4.13.0 in the repository) compiles that source into an installable application package and installs it on an instance; - everything goes through a branch, a pull request and a build before it gets near a shared environment.
The repository is equally clear about what code-first does not mean. Its README calls it "not a rule that every ServiceNow change should be forced into Fluent". Global metadata, instance-managed configuration, unsupported metadata types, vendor-controlled applications and work that genuinely suits update sets or the native builders continue to use the appropriate ServiceNow mechanism. I'll come back to that boundary in detail in part 4.
The toolchain end to end
Here is the reference stack as the repository defines it:
| Layer | Standard | What it does in the flow |
|---|---|---|
| Host VM | Ubuntu 24.04 LTS | Runs Docker and the Coder control plane |
| Workspace platform | Coder (stable channel) | Creates reproducible, disposable developer workspaces from a Terraform template |
| Container runtime | Docker Engine and Compose | Runs Coder, its database and the workspaces themselves |
| Runtime | Node.js 24 LTS, npm | Runs the SDK, TypeScript and project scripts |
| ServiceNow tooling | @servicenow/sdk | Builds, installs, syncs and downloads type definitions |
| Metadata authoring | ServiceNow Fluent | Typed, reviewable definitions of ServiceNow metadata |
| Source control | Git and GitHub | Branches, pull requests, history and audit |
| IDE | VS Code / code-server with the Fluent extension | Editing with in-editor diagnostics |
| Testing | SDK build checks, ATF, project tests | Compile-time and runtime validation |
| Promotion | Branch, PR, DEV, TEST, PROD | Gated movement towards production |
| Secrets | Environment or secret manager only | Nothing sensitive in the repository |
And here is how those pieces connect:
Figure 1.1: End-to-end architecture. A requirement is picked up by an engineer or a non-prod AI agent in a Coder workspace (Node 24, ServiceNow SDK, Fluent, Git), pushed to GitHub as a branch and pull request, then quality gates, DEV/PDI with ATF, TEST, and PROD only after human approval
Reading it from the top: a requirement arrives; an engineer or a controlled AI agent works in a Coder workspace that already has the right Node version, SDK and extensions; changes are made on a feature branch and pushed; a pull request is reviewed and must pass quality gates; the approved build is installed to a development instance where ATF and functional checks run; the change is then promoted to TEST for formal validation and only reaches PROD through an approved release.
Two parts of that picture are still being built. The CI quality gate (issue #9 in the repository) and the formal DEV to TEST to PROD promotion controls (issue #11) are on the roadmap rather than running today. I'll describe them in part 3 as the target design, and I'll be explicit about what is working now.
Git is the source of truth; ServiceNow is the runtime target
The repository's architecture document sets out six principles. They are worth quoting because everything else follows from them.
- Git is the source of truth. For SDK-managed scoped application code, the repository is authoritative. You should be able to recreate the intended application state from a clean clone plus approved environment configuration.
- The instance is a deployment target. The development instance is still essential for runtime behaviour, ServiceNow APIs, security evaluation, UI validation and ATF. It is simply no longer the only place where the application's intent exists.
- Workspaces are disposable; source is persistent. A workspace can be rebuilt without losing anything, because the source lives in Git. Only approved local state such as caches and SDK authentication aliases persists outside Git.
- Secrets are external. Passwords, OAuth secrets, tokens, sessions and private keys never belong in source control.
- Builds are deterministic. Pinned dependency versions,
npm ci, a committed lockfile and a defined Node major version. - Promotion is gated. No direct production deployment from a developer workspace.
The first two principles are the heart of it, and they need a little nuance. Treating Git as authoritative does not make the instance less important. ServiceNow is where Glide APIs actually run, where ACLs are actually evaluated and where ATF actually executes. What changes is the direction of travel: source flows from Git to the instance, and anything that changes on the instance has to flow back into Git through a reviewed change.
Figure 1.2: Git as the source of truth, ServiceNow as the runtime target. Fluent source in Git is built with npm run build and installed with npm run deploy for runtime validation; edits made on the instance come back only through now-sdk transform and a reviewed pull request
ServiceNow's own getting-started guide for the SDK now says this directly: once an app is converted to Fluent and the SDK is used for development, "Git, not a developer instance, is the source of truth for your application's state", and a developer instance "should be treated as disposable and reproducible from Git". The same guide describes now-sdk transform, which pulls changes made on the instance back into Fluent, as "the bridge back to Git", not a substitute for committing.
One practical detail makes this work: the generated src/fluent/generated/keys.ts file. Every Fluent record has a stable identifier (for example Now.ID['br0']), and keys.ts maps those identifiers to real ServiceNow sys_id values. It must be committed with the code that introduces an identifier, otherwise different machines generate different sys_ids and an update on one environment becomes a duplicate insert on another. Part 3 shows how a CI check enforces that.
A hybrid model, deliberately
I want to be clear early that this is not an argument for rewriting everything in TypeScript. The programme uses two delivery tracks that share one way of working (a written spec first, AI-assisted drafting, an independent read-only check, Git as the record and a single handoff report):
- Track A, Fluent and the SDK: new applications or capabilities that the team owns, in their own scope.
- Track B, named update sets: changes to existing, mostly global, shared configuration.
Flow Designer flows, catalogue changes, Discovery patterns and credentials, and fixes to existing global scripts all route to Track B. Data fixes go through a reviewed fix script with explicit approval and sit outside both pipelines. Part 4 contains the full decision table and the reasoning behind it, because getting that boundary wrong is the fastest way to discredit a code-first programme.
Why now: the platform is moving the same way
A few years ago an off-platform, Git-first route on ServiceNow felt like swimming against the tide. That has changed noticeably during 2026.
- The SDK is moving quickly. npm shows five minor releases of
@servicenow/sdkbetween 17 July and 23 September 2026 (4.9.0 to 4.13.0). Recent releases added anow-sdk cicdcommand that wraps the platform's CI/CD API for publishing, installing, rolling back and running ATF suites (4.10.0), aTestSuite()API for ATF suites in Fluent (4.11.0), asynchronous installs by default (4.12.0) and MFA support for basic authentication (4.13.0). That pace is exactly why the repository pins an exact version and treats upgrades as deliberate changes. - ServiceNow published an opinionated SDLC model. The SDK documentation now includes an end-to-end SDLC guide built around source code as the authoritative source, Git for branching and review, direct SDK installs for development instances only, and the Application Repository plus CI/CD APIs for test and production. It states plainly: "do not use the SDK to deploy to production."
- Off-platform agents are supported. ServiceNow's Australia release notes for developers describe building from Cursor, Claude Code, Windsurf and Codex and deploying to the platform, helped by AI-consumable skills in the SDK from version 4.6. At Knowledge 2026 in May, ServiceNow made Build Agent generally available in ServiceNow Studio and extended its skills into Cursor, Windsurf, Claude Code and GitHub Copilot.
- The next family release continues it. ServiceNow's developer community lists Source Control V2 and raw source file editing in ServiceNow Studio among the Brazil features arriving on PDIs from 24 September 2026, with the ServiceNow IDE folded into Studio.
So the code-first route is no longer a workaround. It is one of the supported ways to build on the platform. That does not make it the only way. Teams that prefer to stay on-platform can use Build Agent in Studio with its own source control. The approach in this series suits teams that want the full off-platform engineering toolchain, their own choice of AI agent and a pipeline they control.
Where the programme is today
It is worth being honest about status, because a reference implementation is only useful if you know which parts are proven. This reflects the repository's project board at the time of writing (late September 2026):
Figure 1.3: Programme status by phase in late September 2026. Foundation docs and the workspace template are done; the Docker/Coder host and SDK auth are partly done; the CI gate, ATF and promotion controls are planned; the agent workflow is defined with verification pending
In plain terms:
- Working now: the documented architecture and standards; Docker and Coder running on an interim local host; a Coder workspace template; a Node and SDK toolchain; SDK authentication to a personal developer instance (PDI) with credentials held outside the repository; a reference Fluent application (a table, roles, ACLs, a business rule, a script include module and more) built from source and installed on a PDI; and an agreed routing rule for Fluent versus update sets.
- In progress: the dedicated Ubuntu 24.04 VM with DNS and HTTPS; running the first source-authored ATF test and capturing its evidence; a set of Fluent learning labs; and repointing the independent verification connector at the same PDI the SDK deploys to.
- Planned: a CI quality gate on pull requests, and formal DEV to TEST to PROD promotion with a production approval gate and audit trail.
What the rest of the series covers
- Part 2 builds the workstation: an Ubuntu 24.04 VM, Docker, a Coder template and workspace, Node 24, the SDK, and authentication to instances without ever committing credentials.
- Part 3 walks through the SDK and Fluent workflow: project structure, realistic Fluent examples, build and deploy commands, branching, pull requests, CI quality gates, ATF and promotion from DEV to TEST to PROD.
- Part 4 covers governance: environment tiers, the AI agent access model (LAB, PDI and DEV yes, PROD only with human approval), secrets, audit, and an honest decision guide for when to use Fluent and when to stay with native ServiceNow development.
If you run a ServiceNow platform team and you're weighing up whether this is worth the change, my suggestion is to start where the repository started: one small, team-owned scoped application, one PDI and one pull request. The value becomes obvious the first time you review a change as a readable diff rather than a list of update set records.
The Code-first ServiceNow series
- Code-first ServiceNow: why Git, not the instance, now holds my application (you are here)
- Building a ServiceNow code-first workstation: Ubuntu 24.04, Docker, Coder and Node 24
- From .now.ts to production: the ServiceNow SDK, Fluent and Git workflow
- Governing code-first ServiceNow: environment tiers, AI-agent guardrails and when to stay native
Sources
- My own practice repository (private, not linked): the README, architecture and roadmap notes, the pull request that established the platform, and the issues tracking each workstream.
- ServiceNow SDK: Getting started (Git is your source of truth)
- ServiceNow SDK: SDLC on ServiceNow guide
- ServiceNow SDK release notes on GitHub (4.10.0 to 4.13.0)
- @servicenow/sdk on npm
- ServiceNow Community: Australia, the release where AI delivers for developers
- ServiceNow: Build Agent now works inside every major AI coding tool (Knowledge 2026)
- ServiceNow Community: So, you're getting yourself a Brazil PDI
Code-first is not about abandoning the platform's builders. It is about putting the parts of an application that deserve engineering discipline (scoped tables, roles, ACLs, scripts and tests) somewhere they can be diffed, reviewed and rebuilt, and keeping the instance as the place they run and are validated.
