Code Editor Skeleton Loader — Syntax-Style Shimmer CSS JS
Code Editor Skeleton Loader · Loaders · Plain HTML, CSS & JS · Live preview
Copy & paste
Source Code
<div class="ce-window">
<div class="ce-titlebar">
<span class="ce-dot r"></span><span class="ce-dot y"></span><span class="ce-dot g"></span>
<span class="ce-filename">app.tsx</span>
</div>
<div class="ce-body">
<div class="ce-gutter" id="ceGutter"></div>
<div class="ce-lines" id="ceLines"></div>
</div>
</div>*{box-sizing:border-box;margin:0;padding:0}
body{font-family:system-ui,-apple-system,sans-serif;background:#0b0f1a;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}
.ce-window{width:100%;max-width:480px;background:#0d1117;border:1px solid #21262d;border-radius:12px;overflow:hidden;box-shadow:0 20px 50px rgba(0,0,0,.5)}
.ce-titlebar{display:flex;align-items:center;gap:6px;padding:10px 14px;background:#161b22;border-bottom:1px solid #21262d}
.ce-dot{width:10px;height:10px;border-radius:50%}
.ce-dot.r{background:#f87171}.ce-dot.y{background:#fbbf24}.ce-dot.g{background:#34d399}
.ce-filename{margin-left:6px;font-size:11.5px;color:#7d8590;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.ce-body{display:flex;padding:14px 0;min-height:260px}
.ce-gutter{display:flex;flex-direction:column;gap:11px;padding:0 12px;border-right:1px solid #1c212c}
.ce-gutter span{font-family:ui-monospace,monospace;font-size:11px;color:#30384a;text-align:right;width:16px}
.ce-lines{flex:1;display:flex;flex-direction:column;gap:11px;padding:0 16px}
.ce-line{display:flex;gap:6px;align-items:center;height:12px}
.ce-tok{height:10px;border-radius:4px;background:linear-gradient(90deg,#1a2030 25%,#262e44 37%,#1a2030 63%);background-size:400% 100%;animation:ceShimmer 1.6s ease-in-out infinite}
@keyframes ceShimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}
/* Token color hints, dimmed, to read as syntax highlighting even while placeholder */
.ce-tok.kw{background-image:linear-gradient(90deg,#3a2a4a 25%,#5a3f73 37%,#3a2a4a 63%)}
.ce-tok.fn{background-image:linear-gradient(90deg,#1e3a4a 25%,#2f5a73 37%,#1e3a4a 63%)}
.ce-tok.str{background-image:linear-gradient(90deg,#1e3a2a 25%,#2f5a3f 37%,#1e3a2a 63%)}// Generates a plausible skeleton "code" layout: varied indentation depths,
// varied token widths per line, and occasional short/blank lines, so it
// reads as real source code rather than a generic list of gray bars.
var LINE_COUNT = 16;
var linesEl = document.getElementById('ceLines');
var gutterEl = document.getElementById('ceGutter');
var TOKEN_CLASSES = ['', 'kw', 'fn', 'str'];
function randomInt(min, max) {
return Math.floor(min + Math.random() * (max - min + 1));
}
function buildLine(i) {
var row = document.createElement('div');
row.className = 'ce-line';
// Roughly a third of lines are blank, like real source with breathing room.
if (Math.random() < 0.15) return row;
var indentLevel = randomInt(0, 3);
row.style.marginLeft = (indentLevel * 18) + 'px';
var tokenCount = randomInt(1, 4);
for (var t = 0; t < tokenCount; t++) {
var tok = document.createElement('span');
var cls = TOKEN_CLASSES[randomInt(0, TOKEN_CLASSES.length - 1)];
tok.className = 'ce-tok' + (cls ? ' ' + cls : '');
tok.style.width = randomInt(24, 92) + 'px';
tok.style.animationDelay = (i * 0.03) + 's';
row.appendChild(tok);
}
return row;
}
for (var i = 0; i < LINE_COUNT; i++) {
var num = document.createElement('span');
num.textContent = String(i + 1);
gutterEl.appendChild(num);
linesEl.appendChild(buildLine(i));
}Extend with AI
Take This Snippet Further With AI
The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.
What's included
Features
About this UI Snippet
Code Editor Skeleton Loader — A Placeholder Shaped Like Real Source Code

Generic skeleton loaders — flat gray bars of a few fixed widths — work fine for text and cards, but they read as obviously wrong when the real content is source code. Code has line numbers, wildly varied line lengths, indentation that increases and decreases, and color-coded tokens. This snippet builds a skeleton specifically shaped like a code editor: a titlebar with window dots and a filename, a gutter of line numbers, and a body of shimmer "tokens" arranged with randomized indentation and token counts per line.
Randomized, code-shaped line generation
buildLine(i) doesn't just repeat one bar shape. Each line gets a random indent level (0 to 3, multiplied into a margin-left in steps of 18px) and a random count of 1 to 4 token spans, each with its own randomized width between 24px and 92px. Roughly 15% of lines are left blank, mimicking the breathing room real source files have between logical blocks. The result looks like an actual function body rather than a uniform list.
Tinted tokens hint at syntax highlighting
Instead of every shimmer bar sharing one gray gradient, each token is randomly assigned one of a few tinted gradient classes — a muted purple for kw (keyword-like), blue for fn (call-like), and green for str (string-like) — layered under the same moving shimmer animation. The effect reads as a blurred, out-of-focus glimpse of syntax-highlighted code without needing a real syntax highlighter or language grammar.
A believable gutter
The .ce-gutter renders one real line number per generated line, right-aligned in a muted monospace, exactly matching a real code editor's left column — a detail that does a lot of work to sell the illusion, since a gutter is one of the most recognizable features of any code view at a glance.
Console-style chrome
The titlebar's red/yellow/green window dots and monospace filename label match the same convention used by the typewriter status log loader and countless real editors and terminals, so the component is immediately legible as "code" before a single token has rendered.
Why this beats a generic skeleton for code contexts
A generic list-of-bars skeleton over a code preview area creates a visible mismatch the instant real syntax-highlighted code pops in — the shapes don't rhyme. This skeleton's randomized indentation and varied token widths are deliberately irregular in the same way real code is irregular, so the transition into the real editor or code block feels like a continuation rather than a swap.
Customizing it
Adjust LINE_COUNT, the indent step size, or the token width range to match your actual editor's typical line profile. Add more tinted token classes for a richer syntax illusion, or tie LINE_COUNT to the real file's line count once you know it (from a HEAD request or cached metadata) so the skeleton's height doesn't jump when the real content loads. Pair it with a suspense fallback card for the surrounding page shell.
Step by step
How to Use
- 1Paste HTML, CSS, and JSA code-editor window renders with a titlebar, line-number gutter, and shimmering token lines.
- 2Observe the varied shapesIndentation, token count, and token width differ per line, with occasional blank lines.
- 3Notice the tinted tokensMuted purple, blue, and green shimmer tones hint at keywords, calls, and strings.
- 4Adjust LINE_COUNTChange how many skeleton lines render to match your real editor\u2019s typical height.
- 5Tune indentation and widthsEdit the randomInt ranges for indent level, token count, and token width.
- 6Swap in the real editorReplace this component with your real code view (or CodeMirror/Monaco instance) once content loads.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
A generic skeleton\u2019s uniform bar widths and lack of indentation create a visible mismatch the instant real syntax-highlighted code appears — the shapes don\u2019t resemble each other. This component randomizes indentation, token count, and token width per line specifically so its irregular shape rhymes with how real code actually looks.
Each token span is randomly assigned one of a few CSS classes (kw, fn, str, or none) that layer a tinted gradient under the same shimmer animation used for the base gray tokens. It is not real syntax analysis — just enough color variation to visually suggest highlighted code at a glance.
Set LINE_COUNT to the actual line count of the file you\u2019re about to load, if you know it ahead of time (e.g. from cached file metadata), so the skeleton\u2019s height doesn\u2019t change once the real editor mounts and causes a layout shift.
Yes. Add another class to the TOKEN_CLASSES array in the JS and a matching .ce-tok.yourclass rule in the CSS with its own tinted linear-gradient — the random selection logic picks up new entries automatically.
No. It has no awareness of any programming language — it is a purely decorative placeholder built from randomized shapes and tinted shimmer gradients meant to be swapped out for your real syntax-highlighted content once it loads.
Yes. Move the line-generation logic (indent level, token count, token widths, blank-line chance) into a function that returns an array of line descriptors computed once via useMemo (or your framework\u2019s equivalent) so the random shapes don\u2019t change on every re-render, then map that array to markup.