A Javascript Design Pattern: Configuration Objects within an IIFE
Posted by
admin
Tuesday April
7th
, 2026 4:58
p.m.
/**
* @file
* My theme definitions for some widget.
*/
(function (window) {
'use strict';
window.MyThemes = {
THEMES: {
dark: {
skeletonColor: {
primary: '#F3F5FD',
secondary: '#FFFFFF'
},
fontFamily: 'Helvetica, Arial, sans-serif;',
palette: {
primary: { main: '#FAFAFA', dark: '#7a7a7a', light: '#EEE8E8' },
primaryContrast: { main: '#1A1A1A', dark: '#111214', light: '#1E1E1E' },
accent: { main: '#2A8C24', dark: '#662918', light: '#41AE3A' },
accentContrast: { main: '#FAFAFA', dark: '#dbd8d8', light: '#EEE8E8' },
secondary: { main: '#ffffff', dark: '#3b404d', light: '#5F5F5F' },
tertiary: { main: '#414042', dark: '#272b33', light: '#5F5F5F' },
green: { main: '#5FC046', dark: '#185926', light: '#83D36F' },
red: { main: '#ff0000', dark: '#803630', light: '#E54848' },
separator: {
primary: 'rgba(255,255,255,0.12)',
secondary: 'rgba(255,255,255,0.06)'
},
focus: '#3F9AF5',
autofill: '#2C302B'
},
background: {
base: '#000000',
notification: '#414042',
primary: { main: '#1A1A1A', dark: '#0e0e12', light: '#212121' },
secondary: { main: '#282828', dark: '#191b21', light: '#414042' },
tertiary: { main: '#2E2E2E', dark: '#23262e', light: '#5C5C5C' }
},
shadow: {
normal: '0px 4px 64px 0px #000',
small: '0px 4px 24px 0px rgba(0,0,0,0.64)'
}
},
light: {
skeletonColor: {
primary: '#E8ECF5',
secondary: '#F7F8FC'
},
fontFamily: 'Helvetica, Arial, sans-serif;',
palette: {
primary: { main: '#1A1A1A', dark: '#111111', light: '#333333' },
primaryContrast: { main: '#FAFAFA', dark: '#EEEEEE', light: '#FFFFFF' },
accent: { main: '#2A8C24', dark: '#1B5E20', light: '#41AE3A' },
accentContrast: { main: '#FFFFFF', dark: '#F5F5F5', light: '#FFFFFF' },
secondary: { main: '#333333', dark: '#1A1A1A', light: '#555555' },
tertiary: { main: '#666666', dark: '#444444', light: '#888888' },
green: { main: '#2E7D32', dark: '#1B5E20', light: '#43A047' },
red: { main: '#C62828', dark: '#8B0000', light: '#EF5350' },
separator: {
primary: 'rgba(0,0,0,0.12)',
secondary: 'rgba(0,0,0,0.06)'
},
focus: '#1565C0',
autofill: '#E8F5E9'
},
background: {
base: '#FFFFFF',
notification: '#F5F5F5',
primary: { main: '#FFFFFF', dark: '#F0F0F0', light: '#FAFAFA' },
secondary: { main: '#F5F5F5', dark: '#E8E8E8', light: '#FAFAFA' },
tertiary: { main: '#EEEEEE', dark: '#E0E0E0', light: '#F5F5F5' }
},
shadow: {
normal: '0px 4px 64px 0px rgba(0,0,0,0.15)',
small: '0px 4px 24px 0px rgba(0,0,0,0.10)'
}
}
},
SHARED: {
heatmapWidget: {
heatPalette: {
green: {
'1': '#9BE4AA',
'2': '#7EDC92',
'3': '#61D47A',
'4': '#45CD62',
'5': '#32BA50',
'6': '#2B9E43',
'7': '#238137',
'8': '#1B642B',
'9': '#13481F',
'10': '#0C2B12'
},
red: {
'1': '#FCB2A7',
'2': '#FA9484',
'3': '#F97561',
'4': '#E13030',
'5': '#F6381B',
'6': '#E42609',
'7': '#C12007',
'8': '#9E1A06',
'9': '#7B1405',
'10': '#580E03'
},
blue: {
'1': '#ABC0F7',
'2': '#8AA7F4',
'3': '#698EF1',
'4': '#4774EE',
'5': '#265BEB',
'6': '#1449D9',
'7': '#113EB8',
'8': '#0E3396',
'9': '#0B2775',
'10': '#081C54'
}
}
},
chartPalette: [
'rgba(249,157,153,1)',
'rgba(249,198,154,1)',
'rgba(246,224,155,1)',
'rgba(167,231,197,1)',
'rgba(151,199,245,1)',
'rgba(193,152,245,1)',
'rgba(233,162,234,1)',
'rgba(249,108,102,1)',
'rgba(249,171,105,1)',
'rgba(246,212,106,1)',
'rgba(97,231,160,1)',
'rgba(103,175,245,1)',
'rgba(166,103,245,1)',
'rgba(232,115,234,1)',
'rgba(249,60,52,1)',
'rgba(249,145,55,1)',
'rgba(246,200,57,1)',
'rgba(28,231,123,1)',
'rgba(54,151,245,1)',
'rgba(138,54,245,1)',
'rgba(232,68,234,1)',
'rgba(249,10,0,1)',
'rgba(249,118,5,1)',
'rgba(246,188,7,1)',
'rgba(0,247,116,1)',
'rgba(5,128,245,1)',
'rgba(111,5,245,1)',
'rgba(231,21,234,1)'
],
surfaceChartVisualMapPalette: [
'#FFFCA9',
'#FFCA85',
'#E34E37',
'#FB3D38'
],
eventViewerWidget: {
yellow: '#FCD405'
},
typography: {
header: {
'1': ['font-size: 42px; line-height: 50px; font-weight: 700;'],
'2': ['font-size: 32px; line-height: 38px; font-weight: 400;'],
'3': ['font-size: 26px; line-height: 36px; font-weight: 700;'],
'4': ['font-size: 20px; line-height: 26px; font-weight: 500;'],
'5': ['font-size: 16px; line-height: 28px; font-weight: 700;']
},
body: {
regular: {
'1': ['font-size: 18px; line-height: 24px; font-weight: 400;'],
'2': ['font-size: 16px; line-height: 20px; font-weight: 400;'],
'3': ['font-size: 14px; line-height: 18px; font-weight: 400;'],
'4': ['font-size: 12px; line-height: 16px; font-weight: 400;'],
'5': ['font-size: 13px; line-height: 16px; text-transform: uppercase; letter-spacing: 0.08em;']
},
medium: {
'1': ['font-size: 18px; line-height: 24px; font-weight: 500;'],
'2': ['font-size: 16px; line-height: 20px; font-weight: 500;'],
'3': ['font-size: 14px; line-height: 18px; font-weight: 500;']
}
},
bodyWide: {
regular: {
'1': ['font-size: 18px; line-height: 28px; font-weight: 400;'],
'2': ['font-size: 16px; line-height: 24px; font-weight: 400;'],
'3': ['font-size: 14px; line-height: 22px; font-weight: 400;'],
'4': ['font-size: 12px; line-height: 20px; font-weight: 400;']
},
medium: {
'1': ['font-size: 18px; line-height: 28px; font-weight: 500;'],
'2': ['font-size: 16px; line-height: 24px; font-weight: 500;'],
'3': ['font-size: 14px; line-height: 22px; font-weight: 500;']
}
}
},
zIndex: {
sticky: 10,
popover: 1000
},
borderRadius: {
small: '3px',
normal: '6px'
}
},
build(modeName) {
const mode = this.THEMES[modeName] || this.THEMES.dark;
return {
...this.SHARED,
...mode
};
}
};
})(window);
Yes — this code defines a reusable theme configuration object onwindow, and it wraps everything in an IIFE so it doesn’t leak temporary variables into the global scope. Thebuild(modeName)function returns a merged theme object for eitherdarkorlight, using the selected theme plus shared settings.
This is an Immediately Invoked Function Expression (IIFE): a function that runs as soon as it is defined. It takeswindowas an argument and immediately calls itself with the browser’s globalwindowobject.
'use strict'; enables strict mode, which makes JavaScript use a stricter set of rules and catches more mistakes early.
The global variable it creates
Inside the function, this line attaches a property to the browser’s global window object:
window.MyThemes = { ... }
That means other scripts can later access this as window.MyThemes. This is a common pattern for exposing one public API while keeping everything else inside the closure.
Structure of the object
The object has three main parts:
THEMES: two complete theme definitions,darkandlight.SHARED: values reused by both themes.build(modeName): a function that returns a combined theme object.
Each theme contains nested settings like palette, background, shadow, and fontFamily. These are just plain JavaScript objects grouping related style values together.
This function picks the requested theme by name. If modeName is missing or invalid, it falls back to dark. Then it returns a new object that combines SHARED and the selected theme.
The ... syntax is spread syntax. In an object literal, it copies properties from one object into a new object. If both objects have the same property name, the later one wins.
Important detail about merging
Because return { ...this.SHARED, ...mode } is a shallow merge, it copies top-level properties only. So palette, background, and other nested objects from mode replace any same-named top-level objects in SHARED, rather than deeply merging them.
That means the final result includes:
all shared values from
SHARED, such aschartPalette,typography, andborderRadius.all theme-specific values from either
darkorlight, such aspalette,background,shadow, andskeletonColor.