CS2 Crosshair Generator: Live Preview & Share Code
Free CS2 crosshair generator: dial in your crosshair with a live preview, then copy the exact share code to paste into CS2’s Settings > Crosshair menu, or grab the raw console commands for your autoexec.cfg. Paste any existing share code into the box below to load and tweak it.
.wl-xhair-tool{max-width:900px;margin:0 auto;font-family:inherit;color:inherit}
.wl-xhair-tool *{box-sizing:border-box}
.wl-xhair-grid{display:grid;grid-template-columns:1fr;gap:24px}
@media(min-width:860px){.wl-xhair-grid{grid-template-columns:340px 1fr}}
.wl-xhair-preview-wrap{background:#1b1d21;border-radius:10px;padding:16px;position:sticky;top:16px}
.wl-xhair-preview-canvas{display:block;width:100%;aspect-ratio:1/1;background:#2b2e33;border-radius:6px;image-rendering:pixelated}
.wl-xhair-preview-bg-toggle{display:flex;gap:8px;margin-top:10px;justify-content:center}
.wl-xhair-preview-bg-toggle button{flex:1;padding:6px 8px;font-size:12px;border-radius:6px;border:1px solid #444;background:#222;color:#ccc;cursor:pointer}
.wl-xhair-preview-bg-toggle button.active{background:#73f3f7;color:#111;border-color:#73f3f7}
.wl-xhair-controls{display:flex;flex-direction:column;gap:14px}
.wl-xhair-row{display:flex;align-items:center;gap:12px}
.wl-xhair-row label{flex:0 0 150px;font-size:13px;font-weight:600}
.wl-xhair-row input[type=range]{flex:1}
.wl-xhair-row input[type=number]{width:64px;padding:4px 6px}
.wl-xhair-row .wl-xhair-val{width:44px;text-align:right;font-variant-numeric:tabular-nums;font-size:13px;opacity:0.8}
.wl-xhair-row input[type=color]{width:44px;height:30px;padding:0;border:none;background:none;cursor:pointer}
.wl-xhair-toggle{display:flex;align-items:center;gap:8px}
.wl-xhair-section-title{font-size:14px;font-weight:700;margin:6px 0 -4px;text-transform:uppercase;letter-spacing:.04em;opacity:.7}
.wl-xhair-advanced-toggle{cursor:pointer;font-size:13px;font-weight:600;text-decoration:underline;background:none;border:none;padding:0;color:inherit;margin-top:4px;align-self:flex-start}
.wl-xhair-advanced{display:none;flex-direction:column;gap:14px;border-top:1px dashed #999;padding-top:14px;margin-top:4px}
.wl-xhair-advanced.open{display:flex}
.wl-xhair-output{margin-top:24px;display:flex;flex-direction:column;gap:14px}
.wl-xhair-output-block{background:#f7f8f9;border-radius:8px;padding:14px}
.wl-xhair-output-block h4{margin:0 0 8px;font-size:13px;text-transform:uppercase;letter-spacing:.04em}
.wl-xhair-code-row{display:flex;gap:8px;align-items:center}
.wl-xhair-code-row code{flex:1;background:#fff;border:1px solid #ddd;border-radius:6px;padding:8px 10px;font-size:15px;overflow-x:auto;white-space:nowrap}
.wl-xhair-copy-btn{flex:0 0 auto;padding:8px 14px;border-radius:6px;border:none;background:#2125a7;color:#fff;font-weight:600;cursor:pointer;font-size:13px}
.wl-xhair-copy-btn:hover{opacity:.9}
.wl-xhair-copy-btn.copied{background:#1a7a1a}
.wl-xhair-convars{background:#111;color:#8ee08e;border-radius:6px;padding:10px;font-size:12px;line-height:1.5;overflow-x:auto;white-space:pre;font-family:monospace}
.wl-xhair-import-row{display:flex;gap:8px;margin-bottom:16px}
.wl-xhair-import-row input{flex:1;padding:8px 10px;border:1px solid #ccc;border-radius:6px}
.wl-xhair-import-row button{padding:8px 14px;border-radius:6px;border:1px solid #2125a7;background:#fff;color:#2125a7;font-weight:600;cursor:pointer}
.wl-xhair-error{color:#c0392b;font-size:13px;min-height:18px}
@media(prefers-color-scheme:dark){
.wl-xhair-output-block{background:#22252b}
.wl-xhair-code-row code{background:#16181c;border-color:#333;color:#eee}
.wl-xhair-import-row input{background:#16181c;border-color:#333;color:#eee}
}
(function(){
'use strict';
// ---- Ported from akiver/csgo-sharecode (MIT licensed), verified against the
// CS2/CS:GO crosshair share-code spec: 15-byte structure with a sum-mod-256
// checksum in byte[0], encoded via a 58-char custom dictionary (base61-style,
// visually-unambiguous alphabet) into the CSGO-xxxxx-... share code format.
var DICTIONARY = 'ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789';
var DICTIONARY_LENGTH = BigInt(DICTIONARY.length);
var SHARECODE_PATTERN = /^CSGO(-?[w]{5}){5}$/;
function bytesToHex(bytes) {
return bytes.map(function(b){ return ('0' + (b & 0xff).toString(16)).slice(-2); }).join('');
}
function stringToBytes(str) {
var bytes = [];
for (var i = 0; i < str.length; i += 2) bytes.push(parseInt(str.slice(i, i + 2), 16));
return bytes;
}
function uint8ToInt8(n) { return (n <> 24; }
function sumArray(arr) { return arr.reduce(function(a,b){ return a+b; }, 0); }
function shareCodeToBytes(shareCode) {
if (!shareCode.match(SHARECODE_PATTERN)) throw new Error('Invalid share code');
shareCode = shareCode.replace(/CSGO|-/g, '');
var chars = Array.from(shareCode).reverse();
var big = BigInt(0);
for (var i = 0; i < chars.length; i++) {
big = big * DICTIONARY_LENGTH + BigInt(DICTIONARY.indexOf(chars[i]));
}
var str = big.toString(16).padStart(36, '0');
return stringToBytes(str);
}
function bytesToShareCode(bytes) {
var hex = bytesToHex(bytes);
var total = BigInt('0x' + hex);
var chars = '';
for (var i = 0; i > 4) & 8) === 8,
fixedCrosshairGap: uint8ToInt8(bytes[9]) / 10,
color: bytes[10] & 7,
outlineEnabled: (bytes[10] & 8) === 8,
innerSplitAlpha: (bytes[10] >> 4) / 10,
outerSplitAlpha: (bytes[11] & 0xf) / 10,
splitSizeRatio: (bytes[11] >> 4) / 10,
thickness: bytes[12] / 10,
centerDotEnabled: ((bytes[13] >> 4) & 1) === 1,
deployedWeaponGapEnabled: ((bytes[13] >> 4) & 2) === 2,
alphaEnabled: ((bytes[13] >> 4) & 4) === 4,
tStyleEnabled: ((bytes[13] >> 4) & 8) === 8,
style: (bytes[13] & 0xf) >> 1,
length: bytes[14] / 10
};
}
function encodeCrosshair(c) {
var bytes = [
0,
1,
Math.round(c.gap * 10) & 0xff,
Math.round(c.outline * 2),
c.red,
c.green,
c.blue,
c.alpha,
(c.splitDistance & 7) | (Number(c.followRecoil) << 7),
Math.round(c.fixedCrosshairGap * 10) & 0xff,
(c.color & 7) | (Number(c.outlineEnabled) << 3) | (Math.round(c.innerSplitAlpha * 10) << 4),
Math.round(c.outerSplitAlpha * 10) | (Math.round(c.splitSizeRatio * 10) << 4),
Math.round(c.thickness * 10),
(c.style << 1) | (Number(c.centerDotEnabled) << 4) | (Number(c.deployedWeaponGapEnabled) << 5) | (Number(c.alphaEnabled) << 6) | (Number(c.tStyleEnabled) < 0) {
ctx.fillStyle = 'rgba(0,0,0,0.85)';
var o = c.outline * scale * 0.5;
ctx.fillRect(x - o, y - o, bw + o*2, bh + o*2);
}
ctx.fillStyle = color;
ctx.fillRect(x, y, bw, bh);
}
if (length > 0) {
// right
bar(cx + gap, cy - thickness/2, length, thickness);
// left
bar(cx - gap - length, cy - thickness/2, length, thickness);
// bottom
bar(cx - thickness/2, cy + gap, thickness, length);
// top (skipped entirely for T-style)
if (!c.tStyleEnabled) {
bar(cx - thickness/2, cy - gap - length, thickness, length);
}
}
if (c.centerDotEnabled) {
var dotSize = Math.max(2, thickness);
bar(cx - dotSize/2, cy - dotSize/2, dotSize, dotSize);
}
}
function refresh() {
var c = readState();
try {
var code = encodeCrosshair(c);
sharecodeEl.textContent = code;
convarsEl.textContent = crosshairToConVars(c).trim();
errorEl.textContent = '';
} catch (e) {
errorEl.textContent = 'Could not generate code: ' + e.message;
}
drawPreview(c);
}
// Wire up live value labels + refresh on every input.
['x-length','x-thickness','x-gap','x-outline','x-alpha','x-fixed-gap','x-split-dist','x-split-ratio','x-inner-alpha','x-outer-alpha'].forEach(function(id){
var input = el[id];
var label = document.getElementById('wl-' + id + '-val');
function update() { if (label) label.textContent = input.value; refresh(); }
input.addEventListener('input', update);
});
['x-style','x-tstyle','x-outline-en','x-color','x-alpha-en','x-dot','x-recoil','x-deployed-gap'].forEach(function(id){
el[id].addEventListener('input', refresh);
el[id].addEventListener('change', refresh);
});
document.getElementById('wl-xhair-advanced-toggle').addEventListener('click', function(){
var panel = document.getElementById('wl-xhair-advanced');
var open = panel.classList.toggle('open');
this.textContent = (open ? '− Hide' : '+ Show') + ' dynamic / split crosshair settings';
});
document.querySelectorAll('.wl-xhair-preview-bg-toggle button').forEach(function(btn){
btn.addEventListener('click', function(){
document.querySelectorAll('.wl-xhair-preview-bg-toggle button').forEach(function(b){ b.classList.remove('active'); });
this.classList.add('active');
bgColor = this.getAttribute('data-bg');
refresh();
});
});
function copyText(text, btn) {
navigator.clipboard.writeText(text).then(function(){
var original = btn.textContent;
btn.textContent = 'Copied!';
btn.classList.add('copied');
setTimeout(function(){ btn.textContent = original; btn.classList.remove('copied'); }, 1500);
});
}
document.getElementById('wl-xhair-copy-code').addEventListener('click', function(){
copyText(sharecodeEl.textContent, this);
});
document.getElementById('wl-xhair-copy-convars').addEventListener('click', function(){
copyText(convarsEl.textContent, this);
});
document.getElementById('wl-xhair-import-btn').addEventListener('click', function(){
var input = document.getElementById('wl-xhair-import-input').value.trim();
if (!input) return;
try {
var decoded = decodeCrosshairShareCode(input);
applyState(decoded);
refresh();
errorEl.textContent = '';
} catch (e) {
errorEl.textContent = 'Could not load that code: ' + e.message;
}
});
refresh();
})();
Size & Shape
2.5
0.5
-2
Classic
Classic Static
Legacy
Outline
1
Color
255
Center Dot
3
7
0.3
1
0.5
Share Code (paste into CS2 → Settings → Crosshair → Share/Import)
CSGO-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx