If you hang out in dev forums or browse front-end threads, you’ve probably seen people say things like “you can do that in vanilla JS” or “no framework needed.” The term gets tossed around a lot, sometimes meaning different things to different people.
What is vanilla JavaScript? Is it just ES6 without frameworks, or does it include browser APIs too? How do I build common features like DOM updates, HTTP requests, modules, and simple routing using only the platform?
Also, what are the tradeoffs compared to using a framework, and how should I approach performance and images when building a site in plain JS?
Great question. In practice, “vanilla” JavaScript means using the JavaScript language and standard Web Platform APIs without third-party frameworks or libraries. Think modern JS syntax plus the DOM, Fetch API, URL and History APIs, Web Components or plain HTML, and browser-native modules. It doesn’t exclude ES2015+ features or the module system, and it does not require build tools (unless you choose them).
- Small bundle size and fast initial load
- Fewer dependencies to maintain and audit
- Close alignment with browser capabilities
Tradeoffs include writing more glue code yourself, deciding on patterns and structure, and sometimes adding polyfills for older browsers.
// Create and update elements
const app = document.getElementById('app');
function renderCount(count) {
app.innerHTML = '';
const btn = document.createElement('button');
btn.textContent = `Clicked ${count} times`;
btn.addEventListener('click', () => renderCount(count + 1));
app.appendChild(btn);
}
renderCount(0);Code language: JavaScript (javascript)
async function loadPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=3');
if (!res.ok) throw new Error('Network error');
const posts = await res.json();
document.getElementById('posts').innerHTML = posts
.map(p => `<article><h3>${p.title}</h3><p>${p.body}</p></article>`)
.join('');
}
loadPosts().catch(console.error);Code language: JavaScript (javascript)
async function loadPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=3');
if (!res.ok) throw new Error('Network error');
const posts = await res.json();
document.getElementById('posts').innerHTML = posts
.map(p => `<article><h3>${p.title}</h3><p>${p.body}</p></article>`)
.join('');
}
loadPosts().catch(console.error);Code language: JavaScript (javascript)
const routes = {
'': '<h2>Home</h2>',
'#/about': '<h2>About</h2>',
'#/contact': '<h2>Contact</h2>'
};
function renderRoute() {
const view = routes[location.hash] ?? '<h2>404</h2>';
document.getElementById('view').innerHTML = view;
}
window.addEventListener('hashchange', renderRoute);
renderRoute();Code language: JavaScript (javascript)
- Ship the least JS possible and prefer modern features that don’t need polyfills where you can.
- Use responsive, lazy loaded images. The native HTML image tag guide covers attributes like loading, decoding, sizes, and srcset.
- Audit your pages and apply general web performance practices. This primer on what makes an optimized website is a good checklist.
Once you have a plain JS app, you can still optimize media delivery without adding heavy libraries. Cloudinary lets you deliver responsive, transformed images by URL, which works perfectly with native <img>, srcset, and lazy loading.
<img
loading="lazy"
alt="Hero"
src="https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_800/sample.jpg"
srcset="
https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_480/sample.jpg 480w,
https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_800/sample.jpg 800w,
https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_1200/sample.jpg 1200w"
sizes="(max-width: 600px) 480px, (max-width: 900px) 800px, 1200px"
/>Code language: HTML, XML (xml)
The parameters in the URL handle compression and format selection automatically, so you keep your JS light and let the CDN do the heavy lifting.
- Complex state and many interdependent components
- Routing, data fetching, and caching across multiple views
- Team scale and long-term maintainability
Start with the platform. If complexity grows, layer in small utilities or adopt a framework selectively.
- Vanilla JavaScript means the language plus standard browser APIs, no frameworks required.
- Build with native DOM, Fetch, and ES modules for small, fast sites.
- You can pair vanilla JS with Cloudinary for responsive, optimized media delivery by URL.
- PNG to WebP Converter
- JPG to WebP Converter
- Image Upscaling and Quality Enhancement
- Video as a Service Guide
Ready to optimize your vanilla JS project with fast, responsive media? Sign up for a free Cloudinary account and start transforming and delivering images and video at scale.