We’ve all been there: you open up After Effects to throw together a quick timer or a digital clock, grab a snippet of code online, paste it in, and immediately get hit with that annoying red banner error. If you’re running AE 2022 or anything newer, chances are almost 100% that you’re dealing with an engine mismatch behind the scenes. Below, I’ve got the clean, working expression ready to go, a quick breakdown of the knobs you can tweak, and the exact toggle to make that error disappear.
- Grab the snippet below and paste it straight into Source Text (just Alt-click or Option-click the stopwatch).
- If it throws a red error right away: head to File > Project Settings > Expressions > switch it over to Legacy ExtendScript.
- For the font: grab Digital Dismay (it’s free; just install it before firing up AE so it shows up in your font list).
The Digital Clock Expression
Drop this snippet right into your text layer’s Source Text expression box:
JavaScript
rate = 1;
clockStart = 0;
function timerg(n) {
if (n < 10) return "0" + n;
else return "" + n;
}
clockTime = Math.max(clockStart + rate * (time - inPoint), 0);
t = Math.floor(clockTime);
min = Math.floor((t % 3600) / 60);
sec = Math.floor(t % 60);
min + ":" + timerg(sec);You only really need to care about two variables at the very top:
| Variable | What it does | Example |
|---|---|---|
rate |
Controls speed and direction. 1 runs normal real-time, 2 runs double-time, and -1 turns it into a countdown. |
Set this to -1 when you want a countdown. |
clockStart |
Where the timer begins, measured in seconds. 0 kicks off at 00:00, while 60 starts it at 01:00. |
Set this to 120 to start at 02:00. |
The rest is just simple math doing the heavy lifting for you: timerg() adds a leading zero to single digits so you don't end up with awkward reads like 1:5 instead of 01:05. Math.max(..., 0) acts as a floor, preventing countdowns from rolling into negative numbers once they hit zero. And because it references inPoint, the timer ties directly to wherever your layer starts on the timeline - meaning you can drag the layer around your comp freely without breaking anything.
Whenever you want to build a countdown, just set rate = -1 and feed your total seconds into clockStart. For instance, a 3-minute timer is simply clockStart = 180; rate = -1;. If you ever need a dynamic countdown timer with more control over start and end frames, that guide walks through combining keyframed sliders with expressions for even more flexibility.
How to Fix the JavaScript Engine Error (After Effects 2022+)
This is easily the number-one culprit when older expressions fail in modern AE versions. Starting in AE 2022, Adobe made the newer JavaScript engine the default, but the vast majority of classic expressions floating around online - including this one - were originally written for Legacy ExtendScript. Because the syntax rules differ slightly between the two, they don't always play nicely together.
Here is the quick fix:
- Open up File > Project Settings.
- Hop over to the Expressions tab.
- Flip the Expression Engine dropdown from JavaScript over to Legacy ExtendScript.
- Hit OK.
The error banner should vanish on the spot. Don't worry about this feeling like a dirty hack, either - Adobe intentionally keeps Legacy ExtendScript around because decades of production-tested templates and scripts rely on it. Toggling it for a project won't mess up your setup or cause performance headaches.
A few other quirks you might run into:
| Error | What caused it | How to solve it |
|---|---|---|
| "Unable to parse expression" | Curly "smart quotes" (") snuck in during copy-pasting from a browser |
Delete the quotes and retype them directly in the box |
| Clock jumps or displays weird numbers | Your layer's in-point got pulled earlier than frame 0 on the timeline | Slide the layer’s start point to frame 0 or somewhere after it |
| The font isn't showing up properly | Digital Dismay was installed while AE was already open in the background | Save, quit AE completely, relaunch, and reapply the font from the Character panel |
| Works during RAM preview but breaks on final render | The project was rendered before saving the new Legacy ExtendScript setting | Hit Save right after changing the engine setting, then send it back to render |
Setting Up Your Text Layer
To get to the expression field, twirl open your text layer down in the timeline: go to Text > Source Text, then hold Alt (or Option on Mac) and click the stopwatch next to Source Text. Paste the code into the text area that pops up, and click anywhere in your comp viewer or timeline to confirm.
Before pasting, a good habit is setting your text alignment to right-aligned in the Paragraph panel. That keeps the colon and minutes firmly anchored in place so the whole timer doesn't wiggle as the numbers tick between narrow and wide digits. I also like typing a dummy 88:88 into the layer first so I can clearly see the maximum bounding footprint while laying out my comp.
Building the Classic LED Look
The code gives you the operational timer, but the visual polish comes from how you stack your layers. If you want this to look like a physical seven-segment display instead of just plain computer text, a simple three-layer setup does wonders.
Here’s how to stack them (from top to bottom):
- Active clock layer: This is your live expression layer set to 100% opacity, styled with a punchy, vibrant color (an electric cyan or amber looks great over dark backgrounds).
- Ghost layer: Duplicate your clock layer, clear out the expression, and type a static
88:88. Tint it a neutral dim gray and dial the opacity down to around 15–25%. This replicates the unlit segments of an LED screen resting behind the active digits. - Glow layer: Duplicate that layer once more and drop it to the bottom of the stack. Throw on Effect > Blur & Sharpen > CC Radial Fast Blur, push the Amount to around 30–50, and darken the color slightly. This gives you that authentic, warm light bleed spilling across the housing.
Placing all of this over a dark, moody background makes the whole screen pop immediately. Even if you want to keep things lightweight and skip the blur layer entirely, simply pairing the live numbers with the dim 88:88 ghost layer behind them instantly sells the hardware aesthetic.
It’s the exact same layer-isolation philosophy you'd use when you animate a PNG logo in After Effects: breaking distinct visual roles into separate, dedicated layers gives you full artistic control without cluttering your core setup.
Tailoring How the Clock Behaves
Starting halfway through a comp: You don't need to touch the math at all - just drag the head of the text layer to the exact second or frame where you want the timer to kick off, and it will count from zero starting right there.
Freezing the timer on a frame: If you need the clock to stop at a dramatic moment, drop an Expression Control > Slider Control onto the layer, hook your rate variable up to the slider using the pick whip, and simply keyframe that slider down to 0 wherever you want the display to freeze.
Adding an hours display: If you're building a longer counter, just slip hrs = Math.floor(t / 3600); right above the min line, and adjust your final string output to look like hrs + ":" + min + ":" + timerg(sec);. That said, for 90% of short-form motion design pieces, standard MM:SS does the job cleanly.
Keeping text boxes neat: If changing numbers cause your layout borders or background cards to jump around, pairing this setup with auto-resizing text boxes using sourceRectAtTime lets your bounding boxes expand and contract seamlessly without extra keyframing.
Once you’ve dialed in the ExtendScript toggle, picked a proper segmented font, and set up your layer stack, you’ll have a clean, modular digital clock that you can duplicate and drop into any project just by tweaking two numbers at the top.