CINXE.COM
Server-side web frameworks - Learn web development | MDN
<!doctype html><html lang="en-US" prefix="og: https://ogp.me/ns#"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="icon" href="https://developer.mozilla.org/favicon-48x48.bc390275e955dacb2e65.png"/><link rel="apple-touch-icon" href="https://developer.mozilla.org/apple-touch-icon.528534bba673c38049c2.png"/><meta name="theme-color" content="#ffffff"/><link rel="manifest" href="https://developer.mozilla.org/manifest.f42880861b394dd4dc9b.json"/><link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="MDN Web Docs"/><title>Server-side web frameworks - Learn web development | MDN</title><link rel="alternate" title="Serverseitige Web-Frameworks" href="https://developer.mozilla.org/de/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="de"/><link rel="alternate" title="Frameworks Web de lado servidor" href="https://developer.mozilla.org/es/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="es"/><link rel="alternate" title="Les frameworks web côté serveur" href="https://developer.mozilla.org/fr/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="fr"/><link rel="alternate" title="サーバーサイドウェブフレームワーク" href="https://developer.mozilla.org/ja/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="ja"/><link rel="alternate" title="Server-side web frameworks" href="https://developer.mozilla.org/ko/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="ko"/><link rel="alternate" title="Выполняемые на сервере веб-фреймворки" href="https://developer.mozilla.org/ru/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="ru"/><link rel="alternate" title="服务端 web 框架" href="https://developer.mozilla.org/zh-CN/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="zh"/><link rel="alternate" title="Server-side web frameworks" href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Web_frameworks" hrefLang="en"/><link rel="preload" as="font" type="font/woff2" href="/static/media/Inter.var.c2fe3cb2b7c746f7966a.woff2" crossorigin=""/><link rel="alternate" type="application/rss+xml" title="MDN Blog RSS Feed" href="https://developer.mozilla.org/en-US/blog/rss.xml" hrefLang="en"/><meta name="description" content="This article has shown that web frameworks can make it easier to develop and maintain server-side code. It has also provided a high level overview of a few popular frameworks, and discussed criteria for choosing a web application framework. You should now have at least an idea of how to choose a web framework for your own server-side development. If not, then don't worry — later on in the course we'll give you detailed tutorials on Django and Express to give you some experience of actually working with a web framework."/><meta property="og:url" content="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Web_frameworks"/><meta property="og:title" content="Server-side web frameworks - Learn web development | MDN"/><meta property="og:type" content="website"/><meta property="og:locale" content="en_US"/><meta property="og:description" content="This article has shown that web frameworks can make it easier to develop and maintain server-side code. It has also provided a high level overview of a few popular frameworks, and discussed criteria for choosing a web application framework. You should now have at least an idea of how to choose a web framework for your own server-side development. If not, then don't worry — later on in the course we'll give you detailed tutorials on Django and Express to give you some experience of actually working with a web framework."/><meta property="og:image" content="https://developer.mozilla.org/mdn-social-share.d893525a4fb5fb1f67a2.png"/><meta property="og:image:type" content="image/png"/><meta property="og:image:height" content="1080"/><meta property="og:image:width" content="1920"/><meta property="og:image:alt" content="The MDN Web Docs logo, featuring a blue accent color, displayed on a solid black background."/><meta property="og:site_name" content="MDN Web Docs"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:creator" content="MozDevNet"/><link rel="canonical" href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Web_frameworks"/><style media="print">.article-actions-container,.document-toc-container,.language-menu,.main-menu-toggle,.on-github,.page-footer,.place,.sidebar,.top-banner,.top-navigation-main,ul.prev-next{display:none!important}.main-page-content,.main-page-content pre{padding:2px}.main-page-content pre{border-left-width:2px}</style><script src="/static/js/gtag.js" defer=""></script><script defer="" src="/static/js/main.1b60bff1.js"></script><link href="/static/css/main.959b5ea9.css" rel="stylesheet"/></head><body><script>if(document.body.addEventListener("load",(t=>{t.target.classList.contains("interactive")&&t.target.setAttribute("data-readystate","complete")}),{capture:!0}),window&&document.documentElement){const t={light:"#ffffff",dark:"#1b1b1b"};try{const e=window.localStorage.getItem("theme");e&&(document.documentElement.className=e,document.documentElement.style.backgroundColor=t[e]);const o=window.localStorage.getItem("nop");o&&(document.documentElement.dataset.nop=o)}catch(t){console.warn("Unable to read theme from localStorage",t)}}</script><div id="root"><ul id="nav-access" class="a11y-nav"><li><a id="skip-main" href="#content">Skip to main content</a></li><li><a id="skip-search" href="#top-nav-search-input">Skip to search</a></li><li><a id="skip-select-language" href="#languages-switcher-button">Skip to select language</a></li></ul><div class="page-wrapper category-learn document-page"><div class="top-banner loading"><section class="place top container"></section></div><div class="sticky-header-container"><header class="top-navigation "><div class="container "><div class="top-navigation-wrap"><a href="/en-US/" class="logo" aria-label="MDN homepage"><svg id="mdn-docs-logo" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 694.9 104.4" style="enable-background:new 0 0 694.9 104.4" xml:space="preserve" role="img"><title>MDN Web Docs</title><path d="M40.3 0 11.7 92.1H0L28.5 0h11.8zm10.4 0v92.1H40.3V0h10.4zM91 0 62.5 92.1H50.8L79.3 0H91zm10.4 0v92.1H91V0h10.4z" class="logo-m"></path><path d="M627.9 95.6h67v8.8h-67v-8.8z" class="logo-_"></path><path d="M367 42h-4l-10.7 30.8h-5.5l-10.8-26h-.4l-10.5 26h-5.2L308.7 42h-3.8v-5.6H323V42h-6.5l6.8 20.4h.4l10.3-26h4.7l11.2 26h.5l5.7-20.3h-6.2v-5.6H367V42zm34.9 20c-.4 3.2-2 5.9-4.7 8.2-2.8 2.3-6.5 3.4-11.3 3.4-5.4 0-9.7-1.6-13.1-4.7-3.3-3.2-5-7.7-5-13.7 0-5.7 1.6-10.3 4.7-14s7.4-5.5 12.9-5.5c5.1 0 9.1 1.6 11.9 4.7s4.3 6.9 4.3 11.3c0 1.5-.2 3-.5 4.7h-25.6c.3 7.7 4 11.6 10.9 11.6 2.9 0 5.1-.7 6.5-2 1.5-1.4 2.5-3 3-4.9l6 .9zM394 51.3c.2-2.4-.4-4.7-1.8-6.9s-3.8-3.3-7-3.3c-3.1 0-5.3 1-6.9 3-1.5 2-2.5 4.4-2.8 7.2H394zm51 2.4c0 5-1.3 9.5-4 13.7s-6.9 6.2-12.7 6.2c-6 0-10.3-2.2-12.7-6.7-.1.4-.2 1.4-.4 2.9s-.3 2.5-.4 2.9h-7.3c.3-1.7.6-3.5.8-5.3.3-1.8.4-3.7.4-5.5V22.3h-6v-5.6H416v27c1.1-2.2 2.7-4.1 4.7-5.7 2-1.6 4.8-2.4 8.4-2.4 4.6 0 8.4 1.6 11.4 4.7 3 3.2 4.5 7.6 4.5 13.4zm-7.7.6c0-4.2-1-7.4-3-9.5-2-2.2-4.4-3.3-7.4-3.3-3.4 0-6 1.2-8 3.7-1.9 2.4-2.9 5-3 7.7V57c0 3 1 5.6 3 7.7s4.5 3.1 7.6 3.1c3.6 0 6.3-1.3 8.1-3.9 1.8-2.7 2.7-5.9 2.7-9.6zm69.2 18.5h-13.2v-7.2c-1.2 2.2-2.8 4.1-4.9 5.6-2.1 1.6-4.8 2.4-8.3 2.4-4.8 0-8.7-1.6-11.6-4.9-2.9-3.2-4.3-7.7-4.3-13.3 0-5 1.3-9.6 4-13.7 2.6-4.1 6.9-6.2 12.8-6.2 5.7 0 9.8 2.2 12.3 6.5V22.3h-8.6v-5.6h15.8v50.6h6v5.5zM493.2 56v-4.4c-.1-3-1.2-5.5-3.2-7.3s-4.4-2.8-7.2-2.8c-3.6 0-6.3 1.3-8.2 3.9-1.9 2.6-2.8 5.8-2.8 9.6 0 4.1 1 7.3 3 9.5s4.5 3.3 7.4 3.3c3.2 0 5.8-1.3 7.8-3.8 2.1-2.6 3.1-5.3 3.2-8zm53.1-1.4c0 5.6-1.8 10.2-5.3 13.7s-8.2 5.3-13.9 5.3-10.1-1.7-13.4-5.1c-3.3-3.4-5-7.9-5-13.5 0-5.3 1.6-9.9 4.7-13.7 3.2-3.8 7.9-5.7 14.2-5.7s11 1.9 14.1 5.7c3 3.7 4.6 8.1 4.6 13.3zm-7.7-.2c0-4-1-7.2-3-9.5s-4.8-3.5-8.2-3.5c-3.6 0-6.4 1.2-8.3 3.7s-2.9 5.6-2.9 9.5c0 3.7.9 6.8 2.8 9.4 1.9 2.6 4.6 3.9 8.3 3.9 3.6 0 6.4-1.3 8.4-3.8 1.9-2.6 2.9-5.8 2.9-9.7zm45 5.8c-.4 3.2-1.9 6.3-4.4 9.1-2.5 2.9-6.4 4.3-11.8 4.3-5.2 0-9.4-1.6-12.6-4.8-3.2-3.2-4.8-7.7-4.8-13.7 0-5.5 1.6-10.1 4.7-13.9 3.2-3.8 7.6-5.7 13.2-5.7 2.3 0 4.6.3 6.7.8 2.2.5 4.2 1.5 6.2 2.9l1.5 9.5-5.9.7-1.3-6.1c-2.1-1.2-4.5-1.8-7.2-1.8-3.5 0-6.1 1.2-7.7 3.7-1.7 2.5-2.5 5.7-2.5 9.6 0 4.1.9 7.3 2.7 9.5 1.8 2.3 4.4 3.4 7.8 3.4 5.2 0 8.2-2.9 9.2-8.8l6.2 1.3zm34.7 1.9c0 3.6-1.5 6.5-4.6 8.5s-7 3-11.7 3c-5.7 0-10.6-1.2-14.6-3.6l1.2-8.8 5.7.6-.2 4.7c1.1.5 2.3.9 3.6 1.1s2.6.3 3.9.3c2.4 0 4.5-.4 6.5-1.3 1.9-.9 2.9-2.2 2.9-4.1 0-1.8-.8-3.1-2.3-3.8s-3.5-1.3-5.8-1.7-4.6-.9-6.9-1.4c-2.3-.6-4.2-1.6-5.7-2.9-1.6-1.4-2.3-3.5-2.3-6.3 0-4.1 1.5-6.9 4.6-8.5s6.4-2.4 9.9-2.4c2.6 0 5 .3 7.2.9 2.2.6 4.3 1.4 6.1 2.4l.8 8.8-5.8.7-.8-5.7c-2.3-1-4.7-1.6-7.2-1.6-2.1 0-3.7.4-5.1 1.1-1.3.8-2 2-2 3.8 0 1.7.8 2.9 2.3 3.6 1.5.7 3.4 1.2 5.7 1.6 2.2.4 4.5.8 6.7 1.4 2.2.6 4.1 1.6 5.7 3 1.4 1.6 2.2 3.7 2.2 6.6zM197.6 73.2h-17.1v-5.5h3.8V51.9c0-3.7-.7-6.3-2.1-7.9-1.4-1.6-3.3-2.3-5.7-2.3-3.2 0-5.6 1.1-7.2 3.4s-2.4 4.6-2.5 6.9v15.6h6v5.5h-17.1v-5.5h3.8V51.9c0-3.8-.7-6.4-2.1-7.9-1.4-1.5-3.3-2.3-5.6-2.3-3.2 0-5.5 1.1-7.2 3.3-1.6 2.2-2.4 4.5-2.5 6.9v15.8h6.9v5.5h-20.2v-5.5h6V42.4h-6.1v-5.6h13.4v6.4c1.2-2.1 2.7-3.8 4.7-5.2 2-1.3 4.4-2 7.3-2s5.3.7 7.5 2.1c2.2 1.4 3.7 3.5 4.5 6.4 1.1-2.5 2.7-4.5 4.9-6.1s4.8-2.4 7.9-2.4c3.5 0 6.5 1.1 8.9 3.3s3.7 5.6 3.7 10.2v18.2h6.1v5.5zm42.5 0h-13.2V66c-1.2 2.2-2.8 4.1-4.9 5.6-2.1 1.6-4.8 2.4-8.3 2.4-4.8 0-8.7-1.6-11.6-4.9-2.9-3.2-4.3-7.7-4.3-13.3 0-5 1.3-9.6 4-13.7 2.6-4.1 6.9-6.2 12.8-6.2s9.8 2.2 12.3 6.5V22.7h-8.6v-5.6h15.8v50.6h6v5.5zm-13.3-16.8V52c-.1-3-1.2-5.5-3.2-7.3s-4.4-2.8-7.2-2.8c-3.6 0-6.3 1.3-8.2 3.9-1.9 2.6-2.8 5.8-2.8 9.6 0 4.1 1 7.3 3 9.5s4.5 3.3 7.4 3.3c3.2 0 5.8-1.3 7.8-3.8 2.1-2.6 3.1-5.3 3.2-8zm61.5 16.8H269v-5.5h6V51.9c0-3.7-.7-6.3-2.2-7.9-1.4-1.6-3.4-2.3-5.7-2.3-3.1 0-5.6 1-7.4 3s-2.8 4.4-2.9 7v15.9h6v5.5h-19.3v-5.5h6V42.4h-6.2v-5.6h13.6V43c2.6-4.6 6.8-6.9 12.7-6.9 3.6 0 6.7 1.1 9.2 3.3s3.7 5.6 3.7 10.2v18.2h6v5.4h-.2z" class="logo-text"></path></svg></a><button title="Open main menu" type="button" class="button action has-icon main-menu-toggle" aria-haspopup="menu" aria-label="Open main menu" aria-expanded="false"><span class="button-wrap"><span class="icon icon-menu "></span><span class="visually-hidden">Open main menu</span></span></button></div><div class="top-navigation-main"><nav class="main-nav" aria-label="Main menu"><ul class="main-menu nojs"><li class="top-level-entry-container "><button type="button" id="references-button" class="top-level-entry menu-toggle" aria-controls="references-menu" aria-expanded="false">References</button><a href="/en-US/docs/Web" class="top-level-entry">References</a><ul id="references-menu" class="submenu references hidden inline-submenu-lg" aria-labelledby="references-button"><li class="apis-link-container mobile-only "><a href="/en-US/docs/Web" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Overview / Web Technology</div><p class="submenu-item-description">Web technology reference for developers</p></div></a></li><li class="html-link-container "><a href="/en-US/docs/Web/HTML" class="submenu-item "><div class="submenu-icon html"></div><div class="submenu-content-container"><div class="submenu-item-heading">HTML</div><p class="submenu-item-description">Structure of content on the web</p></div></a></li><li class="css-link-container "><a href="/en-US/docs/Web/CSS" class="submenu-item "><div class="submenu-icon css"></div><div class="submenu-content-container"><div class="submenu-item-heading">CSS</div><p class="submenu-item-description">Code used to describe document style</p></div></a></li><li class="javascript-link-container "><a href="/en-US/docs/Web/JavaScript" class="submenu-item "><div class="submenu-icon javascript"></div><div class="submenu-content-container"><div class="submenu-item-heading">JavaScript</div><p class="submenu-item-description">General-purpose scripting language</p></div></a></li><li class="http-link-container "><a href="/en-US/docs/Web/HTTP" class="submenu-item "><div class="submenu-icon http"></div><div class="submenu-content-container"><div class="submenu-item-heading">HTTP</div><p class="submenu-item-description">Protocol for transmitting web resources</p></div></a></li><li class="apis-link-container "><a href="/en-US/docs/Web/API" class="submenu-item "><div class="submenu-icon apis"></div><div class="submenu-content-container"><div class="submenu-item-heading">Web APIs</div><p class="submenu-item-description">Interfaces for building web applications</p></div></a></li><li class="apis-link-container "><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Web Extensions</div><p class="submenu-item-description">Developing extensions for web browsers</p></div></a></li><li class="apis-link-container desktop-only "><a href="/en-US/docs/Web" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Web Technology</div><p class="submenu-item-description">Web technology reference for developers</p></div></a></li></ul></li><li class="top-level-entry-container active"><button type="button" id="guides-button" class="top-level-entry menu-toggle" aria-controls="guides-menu" aria-expanded="false">Guides</button><a href="/en-US/docs/Learn" class="top-level-entry">Guides</a><ul id="guides-menu" class="submenu guides hidden inline-submenu-lg" aria-labelledby="guides-button"><li class="apis-link-container mobile-only "><a href="/en-US/docs/Learn" class="submenu-item "><div class="submenu-icon learn"></div><div class="submenu-content-container"><div class="submenu-item-heading">Overview / MDN Learning Area</div><p class="submenu-item-description">Learn web development</p></div></a></li><li class="apis-link-container desktop-only "><a href="/en-US/docs/Learn" class="submenu-item "><div class="submenu-icon learn"></div><div class="submenu-content-container"><div class="submenu-item-heading">MDN Learning Area</div><p class="submenu-item-description">Learn web development</p></div></a></li><li class="html-link-container "><a href="/en-US/docs/Learn/HTML" class="submenu-item "><div class="submenu-icon html"></div><div class="submenu-content-container"><div class="submenu-item-heading">HTML</div><p class="submenu-item-description">Learn to structure web content with HTML</p></div></a></li><li class="css-link-container "><a href="/en-US/docs/Learn/CSS" class="submenu-item "><div class="submenu-icon css"></div><div class="submenu-content-container"><div class="submenu-item-heading">CSS</div><p class="submenu-item-description">Learn to style content using CSS</p></div></a></li><li class="javascript-link-container "><a href="/en-US/docs/Learn/JavaScript" class="submenu-item "><div class="submenu-icon javascript"></div><div class="submenu-content-container"><div class="submenu-item-heading">JavaScript</div><p class="submenu-item-description">Learn to run scripts in the browser</p></div></a></li><li class=" "><a href="/en-US/docs/Web/Accessibility" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Accessibility</div><p class="submenu-item-description">Learn to make the web accessible to all</p></div></a></li></ul></li><li class="top-level-entry-container "><button type="button" id="mdn-plus-button" class="top-level-entry menu-toggle" aria-controls="mdn-plus-menu" aria-expanded="false">Plus</button><a href="/en-US/plus" class="top-level-entry">Plus</a><ul id="mdn-plus-menu" class="submenu mdn-plus hidden inline-submenu-lg" aria-labelledby="mdn-plus-button"><li class=" "><a href="/en-US/plus" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Overview</div><p class="submenu-item-description">A customized MDN experience</p></div></a></li><li class=" "><a href="/en-US/plus/ai-help" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">AI Help</div><p class="submenu-item-description">Get real-time assistance and support</p></div></a></li><li class=" "><a href="/en-US/plus/updates" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Updates</div><p class="submenu-item-description">All browser compatibility updates at a glance</p></div></a></li><li class=" "><a href="/en-US/plus/docs/features/overview" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Documentation</div><p class="submenu-item-description">Learn how to use MDN Plus</p></div></a></li><li class=" "><a href="/en-US/plus/docs/faq" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">FAQ</div><p class="submenu-item-description">Frequently asked questions about MDN Plus</p></div></a></li></ul></li><li class="top-level-entry-container "><a class="top-level-entry menu-link" href="/en-US/curriculum/">Curriculum <sup class="new">New</sup></a></li><li class="top-level-entry-container "><a class="top-level-entry menu-link" href="/en-US/blog/">Blog</a></li><li class="top-level-entry-container "><button type="button" id="tools-button" class="top-level-entry menu-toggle" aria-controls="tools-menu" aria-expanded="false">Tools</button><ul id="tools-menu" class="submenu tools hidden inline-submenu-lg" aria-labelledby="tools-button"><li class=" "><a href="/en-US/play" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">Playground</div><p class="submenu-item-description">Write, test and share your code</p></div></a></li><li class=" "><a href="/en-US/observatory" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">HTTP Observatory</div><p class="submenu-item-description">Scan a website for free</p></div></a></li><li class=" "><a href="/en-US/plus/ai-help" class="submenu-item "><div class="submenu-icon"></div><div class="submenu-content-container"><div class="submenu-item-heading">AI Help</div><p class="submenu-item-description">Get real-time assistance and support</p></div></a></li></ul></li></ul></nav><div class="header-search"><form action="/en-US/search" class="search-form search-widget" id="top-nav-search-form" role="search"><label id="top-nav-search-label" for="top-nav-search-input" class="visually-hidden">Search MDN</label><input aria-activedescendant="" aria-autocomplete="list" aria-controls="top-nav-search-menu" aria-expanded="false" aria-labelledby="top-nav-search-label" autoComplete="off" id="top-nav-search-input" role="combobox" type="search" class="search-input-field" name="q" placeholder=" " required="" value=""/><button type="button" class="button action has-icon clear-search-button"><span class="button-wrap"><span class="icon icon-cancel "></span><span class="visually-hidden">Clear search input</span></span></button><button type="submit" class="button action has-icon search-button"><span class="button-wrap"><span class="icon icon-search "></span><span class="visually-hidden">Search</span></span></button><div id="top-nav-search-menu" role="listbox" aria-labelledby="top-nav-search-label"></div></form></div><div class="theme-switcher-menu"><button type="button" class="button action has-icon theme-switcher-menu small" aria-haspopup="menu"><span class="button-wrap"><span class="icon icon-theme-os-default "></span>Theme</span></button></div><ul class="auth-container"><li><a href="/users/fxa/login/authenticate/?next=%2Fen-US%2Fdocs%2FLearn%2FServer-side%2FFirst_steps%2FWeb_frameworks" class="login-link" rel="nofollow">Log in</a></li><li><a href="/users/fxa/login/authenticate/?next=%2Fen-US%2Fdocs%2FLearn%2FServer-side%2FFirst_steps%2FWeb_frameworks" target="_self" rel="nofollow" class="button primary mdn-plus-subscribe-link"><span class="button-wrap">Sign up for free</span></a></li></ul></div></div></header><div class="article-actions-container"><div class="container"><button type="button" class="button action has-icon sidebar-button" aria-label="Expand sidebar" aria-expanded="false" aria-controls="sidebar-quicklinks"><span class="button-wrap"><span class="icon icon-sidebar "></span></span></button><nav class="breadcrumbs-container" aria-label="Breadcrumb"><ol typeof="BreadcrumbList" vocab="https://schema.org/" aria-label="breadcrumbs"><li property="itemListElement" typeof="ListItem"><a href="/en-US/docs/Learn" class="breadcrumb" property="item" typeof="WebPage"><span property="name">Guides</span></a><meta property="position" content="1"/></li><li property="itemListElement" typeof="ListItem"><a href="/en-US/docs/Learn/Server-side" class="breadcrumb" property="item" typeof="WebPage"><span property="name">Server-side website programming</span></a><meta property="position" content="2"/></li><li property="itemListElement" typeof="ListItem"><a href="/en-US/docs/Learn/Server-side/First_steps" class="breadcrumb" property="item" typeof="WebPage"><span property="name">Server-side website programming first steps</span></a><meta property="position" content="3"/></li><li property="itemListElement" typeof="ListItem"><a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks" class="breadcrumb-current-page" property="item" typeof="WebPage"><span property="name">Server-side web frameworks</span></a><meta property="position" content="4"/></li></ol></nav><div class="article-actions"><button type="button" class="button action has-icon article-actions-toggle" aria-label="Article actions"><span class="button-wrap"><span class="icon icon-ellipses "></span><span class="article-actions-dialog-heading">Article Actions</span></span></button><ul class="article-actions-entries"><li class="article-actions-entry"><div class="languages-switcher-menu open-on-focus-within"><button id="languages-switcher-button" type="button" class="button action small has-icon languages-switcher-menu" aria-haspopup="menu"><span class="button-wrap"><span class="icon icon-language "></span>English (US)</span></button><div class="hidden"><ul class="submenu language-menu " aria-labelledby="language-menu-button"><li class=" "><form class="submenu-item locale-redirect-setting"><div class="group"><label class="switch"><input type="checkbox" name="locale-redirect"/><span class="slider"></span><span class="label">Remember language</span></label><a href="https://github.com/orgs/mdn/discussions/739" rel="external noopener noreferrer" target="_blank" title="Enable this setting to automatically switch to this language when it's available. (Click to learn more.)"><span class="icon icon-question-mark "></span></a></div></form></li><li class=" "><a data-locale="de" href="/de/docs/Learn/Server-side/First_steps/Web_frameworks" class="button submenu-item"><span>Deutsch</span><span title="Diese Übersetzung ist Teil eines Experiments."><span class="icon icon-experimental "></span></span></a></li><li class=" "><a data-locale="es" href="/es/docs/Learn/Server-side/First_steps/Web_frameworks" class="button submenu-item"><span>Español</span></a></li><li class=" "><a data-locale="fr" href="/fr/docs/Learn/Server-side/First_steps/Web_frameworks" class="button submenu-item"><span>Français</span></a></li><li class=" "><a data-locale="ja" href="/ja/docs/Learn/Server-side/First_steps/Web_frameworks" class="button submenu-item"><span>日本語</span></a></li><li class=" "><a data-locale="ko" href="/ko/docs/Learn/Server-side/First_steps/Web_frameworks" class="button submenu-item"><span>한국어</span></a></li><li class=" "><a data-locale="ru" href="/ru/docs/Learn/Server-side/First_steps/Web_frameworks" class="button submenu-item"><span>Русский</span></a></li><li class=" "><a data-locale="zh-CN" href="/zh-CN/docs/Learn/Server-side/First_steps/Web_frameworks" class="button submenu-item"><span>中文 (简体)</span></a></li></ul></div></div></li></ul></div></div></div></div><div class="main-wrapper"><div class="sidebar-container"><aside id="sidebar-quicklinks" class="sidebar" data-macro="LearnSidebar"><button type="button" class="button action backdrop" aria-label="Collapse sidebar"><span class="button-wrap"></span></button><nav aria-label="Related Topics" class="sidebar-inner"><header class="sidebar-actions"><section class="sidebar-filter-container"><div class="sidebar-filter "><label id="sidebar-filter-label" class="sidebar-filter-label" for="sidebar-filter-input"><span class="icon icon-filter"></span><span class="visually-hidden">Filter sidebar</span></label><input id="sidebar-filter-input" autoComplete="off" class="sidebar-filter-input-field false" type="text" placeholder="Filter" value=""/><button type="button" class="button action has-icon clear-sidebar-filter-button"><span class="button-wrap"><span class="icon icon-cancel "></span><span class="visually-hidden">Clear filter input</span></span></button></div></section></header><div class="sidebar-inner-nav"><div class="in-nav-toc"><div class="document-toc-container"><section class="document-toc"><header><h2 class="document-toc-heading">In this article</h2></header><ul class="document-toc-list"><li class="document-toc-item "><a class="document-toc-link" href="#overview">Overview</a></li><li class="document-toc-item "><a class="document-toc-link" href="#what_can_a_web_framework_do_for_you">What can a web framework do for you?</a></li><li class="document-toc-item "><a class="document-toc-link" href="#how_to_select_a_web_framework">How to select a web framework</a></li><li class="document-toc-item "><a class="document-toc-link" href="#a_few_good_web_frameworks">A few good web frameworks?</a></li><li class="document-toc-item "><a class="document-toc-link" href="#summary">Summary</a></li></ul></section></div></div><div class="sidebar-body"><ol><li class="section"><a href="/en-US/docs/Learn/Getting_started_with_the_web">Complete beginners start here!</a></li><li><details><summary>Getting started with the web</summary><ol><li><a href="/en-US/docs/Learn/Getting_started_with_the_web">Getting started with the web</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/Installing_basic_software">Installing basic software</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/What_will_your_website_look_like">What will your website look like?</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/Dealing_with_files">Dealing with files</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/HTML_basics">HTML basics</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics">CSS basics</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript basics</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/Publishing_your_website">Publishing your website</a></li><li><a href="/en-US/docs/Learn/Getting_started_with_the_web/How_the_Web_works">How the web works</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/HTML">HTML — Structuring the web</a></li><li><details><summary>Introduction to HTML</summary><ol><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML">Introduction to HTML</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started">Getting started with HTML</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML">What's in the head? Metadata in HTML</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals">HTML text fundamentals</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks">Creating hyperlinks</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Advanced_text_formatting">Advanced text formatting</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure">Document and website structure</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Debugging_HTML">Debugging HTML</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Marking_up_a_letter">Marking up a letter</a></li><li><a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content">Structuring a page of content</a></li></ol></details></li><li><details><summary>Multimedia and embedding</summary><ol><li><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding">Multimedia and embedding</a></li><li><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Images_in_HTML">Images in HTML</a></li><li><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Video_and_audio_content">Video and audio content</a></li><li><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies">From object to iframe — other embedding technologies</a></li><li><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web">Adding vector graphics to the web</a></li><li><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images">Responsive images</a></li><li><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page">Mozilla splash page</a></li></ol></details></li><li><details><summary>HTML tables</summary><ol><li><a href="/en-US/docs/Learn/HTML/Tables">HTML tables</a></li><li><a href="/en-US/docs/Learn/HTML/Tables/Basics">HTML table basics</a></li><li><a href="/en-US/docs/Learn/HTML/Tables/Advanced">HTML table advanced features and accessibility</a></li><li><a href="/en-US/docs/Learn/HTML/Tables/Structuring_planet_data">Structuring planet data</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/CSS">CSS — Styling the web</a></li><li><details><summary>CSS first steps</summary><ol><li><a href="/en-US/docs/Learn/CSS/First_steps">CSS first steps</a></li><li><a href="/en-US/docs/Learn/CSS/First_steps/What_is_CSS">What is CSS?</a></li><li><a href="/en-US/docs/Learn/CSS/First_steps/Getting_started">Getting started with CSS</a></li><li><a href="/en-US/docs/Learn/CSS/First_steps/How_CSS_is_structured">How CSS is structured</a></li><li><a href="/en-US/docs/Learn/CSS/First_steps/How_CSS_works">How CSS works</a></li><li><a href="/en-US/docs/Learn/CSS/First_steps/Styling_a_biography_page">Styling a biography page</a></li></ol></details></li><li><details><summary>CSS building blocks</summary><ol><li><a href="/en-US/docs/Learn/CSS/Building_blocks">CSS building blocks</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Selectors">CSS selectors</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors">Type, class, and ID selectors</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Selectors/Attribute_selectors">Attribute selectors</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements">Pseudo-classes and pseudo-elements</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators">Combinators</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance">Cascade, specificity, and inheritance</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers">Cascade layers</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/The_box_model">The box model</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Backgrounds_and_borders">Backgrounds and borders</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Handling_different_text_directions">Handling different text directions</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Overflowing_content">Overflowing content</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Values_and_units">CSS values and units</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Sizing_items_in_CSS">Sizing items in CSS</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Images_media_form_elements">Images, media, and form elements</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Styling_tables">Styling tables</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Advanced_styling_effects">Advanced styling effects</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Debugging_CSS">Debugging CSS</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Organizing">Organizing your CSS</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Fundamental_CSS_comprehension">Fundamental CSS comprehension</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper">Creating fancy letterheaded paper</a></li><li><a href="/en-US/docs/Learn/CSS/Building_blocks/A_cool_looking_box">A cool-looking box</a></li></ol></details></li><li><details><summary>Styling text</summary><ol><li><a href="/en-US/docs/Learn/CSS/Styling_text">CSS styling text</a></li><li><a href="/en-US/docs/Learn/CSS/Styling_text/Fundamentals">Fundamental text and font styling</a></li><li><a href="/en-US/docs/Learn/CSS/Styling_text/Styling_lists">Styling lists</a></li><li><a href="/en-US/docs/Learn/CSS/Styling_text/Styling_links">Styling links</a></li><li><a href="/en-US/docs/Learn/CSS/Styling_text/Web_fonts">Web fonts</a></li><li><a href="/en-US/docs/Learn/CSS/Styling_text/Typesetting_a_homepage">Typesetting a community school homepage</a></li></ol></details></li><li><details><summary>CSS layout</summary><ol><li><a href="/en-US/docs/Learn/CSS/CSS_layout">CSS layout</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Introduction">Introduction to CSS layout</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Normal_Flow">Normal Flow</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Grids">Grids</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">Floats</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Positioning">Positioning</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Multiple-column_Layout">Multiple-column layout</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design">Responsive design</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Media_queries">Beginner's guide to media queries</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Legacy_Layout_Methods">Legacy layout methods</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Supporting_Older_Browsers">Supporting older browsers</a></li><li><a href="/en-US/docs/Learn/CSS/CSS_layout/Fundamental_Layout_Comprehension">Fundamental layout comprehension</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/JavaScript">JavaScript — Dynamic client-side scripting</a></li><li><details><summary>JavaScript first steps</summary><ol><li><a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript">What is JavaScript?</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/A_first_splash">A first splash into JavaScript</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables">Storing the information you need — Variables</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math">Basic math in JavaScript — numbers and operators</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings">Handling text — strings in JavaScript</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a></li><li><a href="/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator">Silly story generator</a></li></ol></details></li><li><details><summary>JavaScript building blocks</summary><ol><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks">JavaScript building blocks</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Event_bubbling">Event bubbling</a></li><li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li></ol></details></li><li><details><summary>Introducing JavaScript objects</summary><ol><li><a href="/en-US/docs/Learn/JavaScript/Objects">Introducing JavaScript objects</a></li><li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript object basics</a></li><li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li><li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_programming">Object-oriented programming</a></li><li><a href="/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript">Classes in JavaScript</a></li><li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON</a></li><li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li><li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li></ol></details></li><li><details><summary>Asynchronous JavaScript</summary><ol><li><a href="/en-US/docs/Learn/JavaScript/Asynchronous">Asynchronous JavaScript</a></li><li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li><li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">How to use promises</a></li><li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Implementing_a_promise-based_API">How to implement a promise-based API</a></li><li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing_workers">Introducing workers</a></li><li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Sequencing_animations">Sequencing animations</a></li></ol></details></li><li><details><summary>Client-side web APIs</summary><ol><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs">Client-side web APIs</a></li><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Introduction to web APIs</a></li><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulating documents</a></li><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a></li><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third-party APIs</a></li><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></li><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and Audio APIs</a></li><li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/Forms">Web forms — Working with user data</a></li><li><details><summary>Web form building blocks</summary><ol><li><a href="/en-US/docs/Learn/Forms">Web form building blocks</a></li><li><a href="/en-US/docs/Learn/Forms/Your_first_form">Your first form</a></li><li><a href="/en-US/docs/Learn/Forms/How_to_structure_a_web_form">How to structure a web form</a></li><li><a href="/en-US/docs/Learn/Forms/Basic_native_form_controls">Basic native form controls</a></li><li><a href="/en-US/docs/Learn/Forms/HTML5_input_types">The HTML5 input types</a></li><li><a href="/en-US/docs/Learn/Forms/Other_form_controls">Other form controls</a></li><li><a href="/en-US/docs/Learn/Forms/Styling_web_forms">Styling web forms</a></li><li><a href="/en-US/docs/Learn/Forms/Advanced_form_styling">Advanced form styling</a></li><li><a href="/en-US/docs/Learn/Forms/UI_pseudo-classes">UI pseudo-classes</a></li><li><a href="/en-US/docs/Learn/Forms/Form_validation">Client-side form validation</a></li><li><a href="/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data">Sending form data</a></li></ol></details></li><li><details><summary>Advanced web form techniques</summary><ol><li><a href="/en-US/docs/Learn/Forms/How_to_build_custom_form_controls">How to build custom form controls</a></li><li><a href="/en-US/docs/Learn/Forms/Sending_forms_through_JavaScript">Sending forms through JavaScript</a></li><li><a href="/en-US/docs/Learn/Forms/Property_compatibility_table_for_form_controls">CSS property compatibility table for form controls</a></li><li><a href="/en-US/docs/Learn/Forms/HTML_forms_in_legacy_browsers">HTML forms in legacy browsers</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/Accessibility">Accessibility — Make the web usable by everyone</a></li><li><details><summary>Accessibility guides</summary><ol><li><a href="/en-US/docs/Learn/Accessibility">Accessibility</a></li><li><a href="/en-US/docs/Learn/Accessibility/What_is_accessibility">What is accessibility?</a></li><li><a href="/en-US/docs/Learn/Accessibility/HTML">HTML: A good basis for accessibility</a></li><li><a href="/en-US/docs/Learn/Accessibility/CSS_and_JavaScript">CSS and JavaScript accessibility best practices</a></li><li><a href="/en-US/docs/Learn/Accessibility/WAI-ARIA_basics">WAI-ARIA basics</a></li><li><a href="/en-US/docs/Learn/Accessibility/Multimedia">Accessible multimedia</a></li><li><a href="/en-US/docs/Learn/Accessibility/Mobile">Mobile accessibility</a></li><li><a href="/en-US/docs/Learn/Accessibility/Accessibility_troubleshooting">Assessment: Accessibility troubleshooting</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/Performance">Performance — Making websites fast and responsive</a></li><li><details><summary>Performance guides</summary><ol><li><a href="/en-US/docs/Learn/Performance">Web performance</a></li><li><a href="/en-US/docs/Learn/Performance/why_web_performance">The "why" of web performance</a></li><li><a href="/en-US/docs/Learn/Performance/What_is_web_performance">What is web performance?</a></li><li><a href="/en-US/docs/Learn/Performance/Perceived_performance">Perceived performance</a></li><li><a href="/en-US/docs/Learn/Performance/Measuring_performance">Measuring performance</a></li><li><a href="/en-US/docs/Learn/Performance/Multimedia">Multimedia: Images</a></li><li><a href="/en-US/docs/Learn/Performance/video">Multimedia: video</a></li><li><a href="/en-US/docs/Learn/Performance/JavaScript">JavaScript performance optimization</a></li><li><a href="/en-US/docs/Learn/Performance/HTML">HTML performance optimization</a></li><li><a href="/en-US/docs/Learn/Performance/CSS">CSS performance optimization</a></li><li><a href="/en-US/docs/Learn/Performance/business_case_for_performance">The business case for web performance</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/MathML">MathML — Writing mathematics with MathML</a></li><li><details><summary>MathML first steps</summary><ol><li><a href="/en-US/docs/Learn/MathML/First_steps">MathML first steps</a></li><li><a href="/en-US/docs/Learn/MathML/First_steps/Getting_started">Getting started with MathML</a></li><li><a href="/en-US/docs/Learn/MathML/First_steps/Text_containers">MathML Text Containers</a></li><li><a href="/en-US/docs/Learn/MathML/First_steps/Fractions_and_roots">MathML fractions and roots</a></li><li><a href="/en-US/docs/Learn/MathML/First_steps/Scripts">MathML scripted elements</a></li><li><a href="/en-US/docs/Learn/MathML/First_steps/Tables">MathML tables</a></li><li><a href="/en-US/docs/Learn/MathML/First_steps/Three_famous_mathematical_formulas">Three famous mathematical formulas</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/../Games">Games — Developing games for the web</a></li><li><details><summary>Guides and tutorials</summary><ol><li><a href="/en-US/docs/Games/Introduction">Introduction to game development for the Web</a></li><li><a href="/en-US/docs/Games/Techniques">Techniques for game development</a></li><li><a href="/en-US/docs/Games/Tutorials">Tutorials</a></li><li><a href="/en-US/docs/Games/Publishing_games">Publishing games</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/Tools_and_testing">Tools and testing</a></li><li><details><summary>Client-side web development tools</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools">Understanding client-side web development tools</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview">Client-side tooling overview</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">Command line crash course</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management">Package management basics</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Introducing_complete_toolchain">Introducing a complete toolchain</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Deployment">Deploying our app</a></li></ol></details></li><li><details><summary>Introduction to client-side frameworks</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Introduction to client-side frameworks</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">Framework main features</a></li></ol></details></li><li><details><summary>React</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Getting started with React</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">Beginning our React todo list</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">Componentizing our React app</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React interactivity: Events and state</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React interactivity: Editing, filtering, conditional rendering</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">Accessibility in React</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React resources</a></li></ol></details></li><li><details><summary>Ember</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Getting started with Ember</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember app structure and componentization</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember interactivity: Events, classes and state</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember Interactivity: Footer functionality, conditional rendering</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Routing in Ember</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember resources and troubleshooting</a></li></ol></details></li><li><details><summary>Vue</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Getting started with Vue</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">Creating our first Vue component</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">Rendering a list of Vue components</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">Adding a new todo form: Vue events, methods, and models</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">Styling Vue components with CSS</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">Using Vue computed properties</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue conditional rendering: editing existing todos</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">Vue refs and lifecycle methods for focus management</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue resources</a></li></ol></details></li><li><details><summary>Svelte</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started">Getting started with Svelte</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning">Starting our Svelte to-do list app</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props">Dynamic behavior in Svelte: working with variables and props</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components">Componentizing our Svelte app</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility">Advanced Svelte: Reactivity, lifecycle, accessibility</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores">Working with Svelte stores</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript">TypeScript support in Svelte</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next">Deployment and next steps</a></li></ol></details></li><li><details><summary>Angular</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_getting_started">Getting started with Angular</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_todo_list_beginning">Beginning our Angular todo list app</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_styling">Styling our Angular app</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_item_component">Creating an item component</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_filtering">Filtering our to-do items</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_building">Building Angular applications and further resources</a></li></ol></details></li><li><details><summary>Git and GitHub</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/GitHub">Git and GitHub</a></li></ol></details></li><li><details><summary>Cross browser testing</summary><ol><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing">Cross browser testing</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction to cross-browser testing</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Strategies for carrying out testing</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Handling common HTML and CSS problems</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li><li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/Server-side">Server-side website programming</a></li><li><details open=""><summary>First steps</summary><ol><li><a href="/en-US/docs/Learn/Server-side/First_steps">Server-side website programming first steps</a></li><li><a href="/en-US/docs/Learn/Server-side/First_steps/Introduction">Introduction to the server side</a></li><li><a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">Client-Server Overview</a></li><li><em><a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks" aria-current="page">Server-side web frameworks</a></em></li><li><a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a></li></ol></details></li><li><details><summary>Django web framework (Python)</summary><ol><li><a href="/en-US/docs/Learn/Server-side/Django">Django Web Framework (Python)</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li><li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">Assessment: DIY Django mini blog</a></li></ol></details></li><li><details><summary>Express Web Framework (Node.js/JavaScript)</summary><ol><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs">Express web framework (Node.js/JavaScript)</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node development environment</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li><li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li></ol></details></li><li class="section"><a href="/en-US/docs/Learn/Common_questions">Further resources</a></li><li><details><summary>Common questions</summary><ol><li><a href="/en-US/docs/Learn/Common_questions">Common questions</a></li><li><a href="/en-US/docs/Learn/HTML/Howto">Use HTML to solve common problems</a></li><li><a href="/en-US/docs/Learn/CSS/Howto">Use CSS to solve common problems</a></li><li><a href="/en-US/docs/Learn/JavaScript/Howto">Solve common problems in your JavaScript code</a></li><li><a href="/en-US/docs/Learn/Common_questions/Web_mechanics">Web mechanics</a></li><li><a href="/en-US/docs/Learn/Common_questions/Tools_and_setup">Tools and setup</a></li><li><a href="/en-US/docs/Learn/Common_questions/Design_and_accessibility">Design and accessibility</a></li></ol></details></li></ol></div></div><section class="place side"></section></nav></aside><div class="toc-container"><aside class="toc"><nav><div class="document-toc-container"><section class="document-toc"><header><h2 class="document-toc-heading">In this article</h2></header><ul class="document-toc-list"><li class="document-toc-item "><a class="document-toc-link" href="#overview">Overview</a></li><li class="document-toc-item "><a class="document-toc-link" href="#what_can_a_web_framework_do_for_you">What can a web framework do for you?</a></li><li class="document-toc-item "><a class="document-toc-link" href="#how_to_select_a_web_framework">How to select a web framework</a></li><li class="document-toc-item "><a class="document-toc-link" href="#a_few_good_web_frameworks">A few good web frameworks?</a></li><li class="document-toc-item "><a class="document-toc-link" href="#summary">Summary</a></li></ul></section></div></nav></aside><section class="place side"></section></div></div><main id="content" class="main-content "><article class="main-page-content" lang="en-US"><header><h1>Server-side web frameworks</h1></header><div class="section-content"><ul class="prev-next"> <li><a class="button secondary" href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview"><span class="button-wrap"> Previous </span></a></li> <li><a class="button secondary" href="/en-US/docs/Learn/Server-side/First_steps"><span class="button-wrap"> Overview: Server-side website programming first steps</span></a></li> <li><a class="button secondary" href="/en-US/docs/Learn/Server-side/First_steps/Website_security"><span class="button-wrap"> Next </span></a></li> </ul> <p>The previous article showed you what the communication between web clients and servers looks like, the nature of HTTP requests and responses, and what a server-side web application needs to do in order to respond to requests from a web browser. With this knowledge under our belt, it's time to explore how web frameworks can simplify these tasks, and give you an idea of how you'd choose a framework for your first server-side web application.</p> <figure class="table-container"><table> <tbody> <tr> <th scope="row">Prerequisites:</th> <td> Basic understanding of how server-side code handles and responds to HTTP requests (see <a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">Client-Server overview</a>). </td> </tr> <tr> <th scope="row">Objective:</th> <td> To understand how web frameworks can simplify development/maintenance of server-side code and to get readers thinking about selecting a framework for their own development. </td> </tr> </tbody> </table></figure> <p>The following sections illustrate some points using code fragments taken from real web frameworks. Don't be concerned if it doesn't <strong>all</strong> make sense now; we'll be working you through the code in our framework-specific modules.</p></div><section aria-labelledby="overview"><h2 id="overview"><a href="#overview">Overview</a></h2><div class="section-content"><p>Server-side web frameworks (a.k.a. "web application frameworks") are software frameworks that make it easier to write, maintain and scale web applications. They provide tools and libraries that simplify common web development tasks, including routing URLs to appropriate handlers, interacting with databases, supporting sessions and user authorization, formatting output (e.g. HTML, JSON, XML), and improving security against web attacks.</p> <p>The next section provides a bit more detail about how web frameworks can ease web application development. We then explain some of the criteria you can use for choosing a web framework, and then list some of your options.</p></div></section><section aria-labelledby="what_can_a_web_framework_do_for_you"><h2 id="what_can_a_web_framework_do_for_you"><a href="#what_can_a_web_framework_do_for_you">What can a web framework do for you?</a></h2><div class="section-content"><p>Web frameworks provide tools and libraries to simplify common web development operations. You don't <em>have</em> to use a server-side web framework, but it is strongly advised — it will make your life a lot easier.</p> <p>This section discusses some of the functionality that is often provided by web frameworks (not every framework will necessarily provide all of these features!).</p></div></section><section aria-labelledby="work_directly_with_http_requests_and_responses"><h3 id="work_directly_with_http_requests_and_responses"><a href="#work_directly_with_http_requests_and_responses">Work directly with HTTP requests and responses</a></h3><div class="section-content"><p>As we saw in the last article, web servers and browsers communicate via the HTTP protocol — servers wait for HTTP requests from the browser and then return information in HTTP responses. Web frameworks allow you to write simplified syntax that will generate server-side code to work with these requests and responses. This means that you will have an easier job, interacting with easier, higher-level code rather than lower level networking primitives.</p> <p>The example below shows how this works in the Django (Python) web framework. Every "view" function (a request handler) receives an <code>HttpRequest</code> object containing request information, and is required to return an <code>HttpResponse</code> object with the formatted output (in this case a string).</p> <div class="code-example"><div class="example-header"><span class="language-name">python</span></div><pre class="brush: python notranslate"><code># Django view function from django.http import HttpResponse def index(request): # Get an HttpRequest (request) # perform operations using information from the request. # Return HttpResponse return HttpResponse('Output string to return') </code></pre></div></div></section><section aria-labelledby="route_requests_to_the_appropriate_handler"><h3 id="route_requests_to_the_appropriate_handler"><a href="#route_requests_to_the_appropriate_handler">Route requests to the appropriate handler</a></h3><div class="section-content"><p>Most sites will provide a number of different resources, accessible through distinct URLs. Handling these all in one function would be hard to maintain, so web frameworks provide simple mechanisms to map URL patterns to specific handler functions. This approach also has benefits in terms of maintenance, because you can change the URL used to deliver a particular feature without having to change the underlying code.</p> <p>Different frameworks use different mechanisms for the mapping. For example, the Flask (Python) web framework adds routes to view functions using a decorator.</p> <div class="code-example"><div class="example-header"><span class="language-name">python</span></div><pre class="brush: python notranslate"><code>@app.route("/") def hello(): return "Hello World!" </code></pre></div> <p>While Django expects developers to define a list of URL mappings between a URL pattern and a view function.</p> <div class="code-example"><div class="example-header"><span class="language-name">python</span></div><pre class="brush: python notranslate"><code>urlpatterns = [ url(r'^$', views.index), # example: /best/my_team_name/5/ url(r'^best/(?P<team_name>\w+?)/(?P<team_number>[0-9]+)/$', views.best), ] </code></pre></div></div></section><section aria-labelledby="make_it_easy_to_access_data_in_the_request"><h3 id="make_it_easy_to_access_data_in_the_request"><a href="#make_it_easy_to_access_data_in_the_request">Make it easy to access data in the request</a></h3><div class="section-content"><p>Data can be encoded in an HTTP request in a number of ways. An HTTP <code>GET</code> request to get files or data from the server may encode what data is required in URL parameters or within the URL structure. An HTTP <code>POST</code> request to update a resource on the server will instead include the update information as "POST data" within the body of the request. The HTTP request may also include information about the current session or user in a client-side cookie.</p> <p>Web frameworks provide programming-language-appropriate mechanisms to access this information. For example, the <code>HttpRequest</code> object that Django passes to every view function contains methods and properties for accessing the target URL, the type of request (e.g. an HTTP <code>GET</code>), <code>GET</code> or <code>POST</code> parameters, cookie and session data, etc. Django can also pass information encoded in the structure of the URL by defining "capture patterns" in the URL mapper (see the last code fragment in the section above).</p></div></section><section aria-labelledby="abstract_and_simplify_database_access"><h3 id="abstract_and_simplify_database_access"><a href="#abstract_and_simplify_database_access">Abstract and simplify database access</a></h3><div class="section-content"><p>Websites use databases to store information both to be shared with users, and about users. Web frameworks often provide a database layer that abstracts database read, write, query, and delete operations. This abstraction layer is referred to as an Object-Relational Mapper (ORM).</p> <p>Using an ORM has two benefits:</p> <ul> <li>You can replace the underlying database without necessarily needing to change the code that uses it. This allows developers to optimize for the characteristics of different databases based on their usage.</li> <li>Basic validation of data can be implemented within the framework. This makes it easier and safer to check that data is stored in the correct type of database field, has the correct format (e.g. an email address), and isn't malicious in any way (hackers can use certain patterns of code to do bad things such as deleting database records).</li> </ul> <p>For example, the Django web framework provides an ORM, and refers to the object used to define the structure of a record as the <em>model</em>. The model specifies the field <em>types</em> to be stored, which may provide field-level validation on what information can be stored (e.g. an email field would only allow valid email addresses). The field definitions may also specify their maximum size, default values, selection list options, help text for documentation, label text for forms etc. The model doesn't state any information about the underlying database as that is a configuration setting that may be changed separately of our code.</p> <p>The first code snippet below shows a very simple Django model for a <code>Team</code> object. This stores the team name and team level as character fields and specifies a maximum number of characters to be stored for each record. The <code>team_level</code> is a choice field, so we also provide a mapping between choices to be displayed and data to be stored, along with a default value.</p> <div class="code-example"><div class="example-header"><span class="language-name">python</span></div><pre class="brush: python notranslate"><code>#best/models.py from django.db import models class Team(models.Model): team_name = models.CharField(max_length=40) TEAM_LEVELS = ( ('U09', 'Under 09s'), ('U10', 'Under 10s'), ('U11', 'Under 11s'), # List our other teams ) team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11') </code></pre></div> <p>The Django model provides a simple query API for searching the database. This can match against a number of fields at a time using different criteria (e.g. exact, case-insensitive, greater than, etc.), and can support complex statements (for example, you can specify a search on U11 teams that have a team name that starts with "Fr" or ends with "al").</p> <p>The second code snippet shows a view function (resource handler) for displaying all of our U09 teams. In this case we specify that we want to filter for all records where the <code>team_level</code> field has exactly the text 'U09' (note below how this criteria is passed to the <code>filter()</code> function as an argument with field name and match type separated by double underscores: <strong>team_level__exact</strong>).</p> <div class="code-example"><div class="example-header"><span class="language-name">python</span></div><pre class="brush: python notranslate"><code>#best/views.py from django.shortcuts import render from .models import Team def youngest(request): list_teams = Team.objects.filter(team_level__exact="U09") context = {'youngest_teams': list_teams} return render(request, 'best/index.html', context) </code></pre></div></div></section><section aria-labelledby="rendering_data"><h3 id="rendering_data"><a href="#rendering_data">Rendering data</a></h3><div class="section-content"><p>Web frameworks often provide templating systems. These allow you to specify the structure of an output document, using placeholders for data that will be added when a page is generated. Templates are often used to create HTML, but can also create other types of documents.</p> <p>Web frameworks often provide a mechanism to make it easy to generate other formats from stored data, including <a href="/en-US/docs/Glossary/JSON">JSON</a> and <a href="/en-US/docs/Glossary/XML">XML</a>.</p> <p>For example, the Django template system allows you to specify variables using a "double-handlebars" syntax (e.g. <code>{{ variable_name }}</code>), which will be replaced by values passed in from the view function when a page is rendered. The template system also provides support for expressions (with syntax: <code>{% expression %}</code>), which allow templates to perform simple operations like iterating list values passed into the template.</p> <div class="notecard note"> <p><strong>Note:</strong> Many other templating systems use a similar syntax, e.g.: Jinja2 (Python), handlebars (JavaScript), moustache (JavaScript), etc.</p> </div> <p>The code snippet below shows how this works. Continuing the "youngest team" example from the previous section, the HTML template is passed a list variable called <code>youngest_teams</code> by the view. Inside the HTML skeleton we have an expression that first checks if the <code>youngest_teams</code> variable exists, and then iterates it in a <code>for</code> loop. On each iteration the template displays the team's <code>team_name</code> value in a list item.</p> <div class="code-example"><div class="example-header"><span class="language-name">django</span></div><pre class="brush: django notranslate"><code>#best/templates/best/index.html <!doctype html> <html lang="en"> <body> {% if youngest_teams %} <ul> {% for team in youngest_teams %} <li>{{ team.team_name }}</li> {% endfor %} </ul> {% else %} <p>No teams are available.</p> {% endif %} </body> </html> </code></pre></div></div></section><section aria-labelledby="how_to_select_a_web_framework"><h2 id="how_to_select_a_web_framework"><a href="#how_to_select_a_web_framework">How to select a web framework</a></h2><div class="section-content"><p>Numerous web frameworks exist for almost every programming language you might want to use (we list a few of the more popular frameworks in the following section). With so many choices, it can become difficult to work out what framework provides the best starting point for your new web application.</p> <p>Some of the factors that may affect your decision are:</p> <ul> <li> <p><strong>Effort to learn:</strong> The effort to learn a web framework depends on how familiar you are with the underlying programming language, the consistency of its API, the quality of its documentation, and the size and activity of its community. If you're starting from absolutely no programming experience then consider Django (it is one of the easiest to learn based on the above criteria). If you are part of a development team that already has significant experience with a particular web framework or programming language, then it makes sense to stick with that.</p> </li> <li> <p><strong>Productivity:</strong> Productivity is a measure of how quickly you can create new features once you are familiar with the framework, and includes both the effort to write and maintain code (since you can't write new features while old ones are broken). Many of the factors affecting productivity are similar to those for "Effort to learn" — e.g. documentation, community, programming experience, etc. — other factors include:</p> <ul> <li><em>Framework purpose/origin</em>: Some web frameworks were initially created to solve certain types of problems, and remain <em>better</em> at creating web apps with similar constraints. For example, Django was created to support development of a newspaper website, so it's good for blogs and other sites that involve publishing things. By contrast, Flask is a much lighter-weight framework and is great for creating web apps running on embedded devices.</li> <li><em>Opinionated vs. unopinionated</em>: An opinionated framework is one in which there are recommended "best" ways to solve a particular problem. Opinionated frameworks tend to be more productive when you're trying to solve common problems, because they lead you in the right direction, however they are sometimes less flexible.</li> <li><em>Batteries included vs. get it yourself</em>: Some web frameworks include tools/libraries that address every problem their developers can think "by default", while more lightweight frameworks expect web developers to pick and choose solution to problems from separate libraries (Django is an example of the former, while Flask is an example of a very light-weight framework). Frameworks that include everything are often easier to get started with because you already have everything you need, and the chances are that it is well integrated and well documented. However if a smaller framework has everything you (will ever) need then it can run in more constrained environments and will have a smaller and easier subset of things to learn.</li> <li><em>Whether or not the framework encourages good development practices</em>: For example, a framework that encourages a <a href="/en-US/docs/Glossary/MVC">Model-View-Controller</a> architecture to separate code into logical functions will result in more maintainable code than one that has no expectations on developers. Similarly, framework design can have a large impact on how easy it is to test and re-use code.</li> </ul> </li> <li> <p><strong>Performance of the framework/programming language:</strong> Usually "speed" is not the biggest factor in selection because even relatively slow runtimes like Python are more than "good enough" for mid-sized sites running on moderate hardware. The perceived speed benefits of another language, e.g. C++ or JavaScript, may well be offset by the costs of learning and maintenance.</p> </li> <li> <p><strong>Caching support:</strong> As your website becomes more successful then you may find that it can no longer cope with the number of requests it is receiving as users access it. At this point you may consider adding support for caching. Caching is an optimization where you store all or part of a web response so that it does not have to be recalculated on subsequent requests. Returning a cached response is much faster than calculating one in the first place. Caching can be implemented in your code or in the server (see <a href="https://en.wikipedia.org/wiki/Reverse_proxy" class="external" target="_blank">reverse proxy</a>). Web frameworks will have different levels of support for defining what content can be cached.</p> </li> <li> <p><strong>Scalability:</strong> Once your website is fantastically successful you will exhaust the benefits of caching and even reach the limits of <em>vertical scaling</em> (running your web application on more powerful hardware). At this point you may need to <em>scale horizontally</em> (share the load by distributing your site across a number of web servers and databases) or scale "geographically" because some of your customers are based a long way away from your server. The web framework you choose can make a big difference on how easy it is to scale your site.</p> </li> <li> <p><strong>Web security:</strong> Some web frameworks provide better support for handling common web attacks. Django for example sanitizes all user input from HTML templates so that user-entered JavaScript cannot be run. Other frameworks provide similar protection, but it is not always enabled by default.</p> </li> </ul> <p>There are many other possible factors, including licensing, whether or not the framework is under active development, etc.</p> <p>If you're an absolute beginner at programming then you'll probably choose your framework based on "ease of learning". In addition to "ease of use" of the language itself, high quality documentation/tutorials and an active community helping new users are your most valuable resources. We've chosen <a href="https://www.djangoproject.com/" class="external" target="_blank">Django</a> (Python) and <a href="https://expressjs.com/" class="external" target="_blank">Express</a> (Node/JavaScript) to write our examples later on in the course, mainly because they are easy to learn and have good support.</p> <div class="notecard note"> <p><strong>Note:</strong> Let's go to the main websites for <a href="https://www.djangoproject.com/" class="external" target="_blank">Django</a> (Python) and <a href="https://expressjs.com/" class="external" target="_blank">Express</a> (Node/JavaScript) and check out their documentation and community.</p> <ol> <li> <p>Navigate to the main sites (linked above)</p> <ul> <li>Click on the Documentation menu links (named things like "Documentation, Guide, API Reference, Getting Started", etc.).</li> <li>Can you see topics showing how to set up URL routing, templates, and databases/models?</li> <li>Are the documents clear?</li> </ul> </li> <li> <p>Navigate to mailing lists for each site (accessible from Community links).</p> <ul> <li>How many questions have been posted in the last few days</li> <li>How many have responses?</li> <li>Do they have an active community?</li> </ul> </li> </ol> </div></div></section><section aria-labelledby="a_few_good_web_frameworks"><h2 id="a_few_good_web_frameworks"><a href="#a_few_good_web_frameworks">A few good web frameworks?</a></h2><div class="section-content"><p>Let's now move on, and discuss a few specific server-side web frameworks.</p> <p>The server-side frameworks below represent <em>a few</em> of the most popular available at the time of writing. All of them have everything you need to be productive — they are open source, are under active development, have enthusiastic communities creating documentation and helping users on discussion boards, and are used in large numbers of high-profile websites. There are many other great server-side frameworks that you can discover using a basic internet search.</p> <div class="notecard note"> <p><strong>Note:</strong> Descriptions come (partially) from the framework websites!</p> </div></div></section><section aria-labelledby="django_python"><h3 id="django_python"><a href="#django_python">Django (Python)</a></h3><div class="section-content"><p><a href="https://www.djangoproject.com/" class="external" target="_blank">Django</a> is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel. It's free and open source.</p> <p>Django follows the "Batteries included" philosophy and provides almost everything most developers might want to do "out of the box". Because everything is included, it all works together, follows consistent design principles, and has extensive and up-to-date documentation. It is also fast, secure, and very scalable. Being based on Python, Django code is easy to read and to maintain.</p> <p>Popular sites using Django (from Django home page) include: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest, Open Stack.</p></div></section><section aria-labelledby="flask_python"><h3 id="flask_python"><a href="#flask_python">Flask (Python)</a></h3><div class="section-content"><p><a href="https://flask.palletsprojects.com/" class="external" target="_blank">Flask</a> is a microframework for Python.</p> <p>While minimalist, Flask can create serious websites out of the box. It contains a development server and debugger, and includes support for <a href="https://github.com/pallets/jinja" class="external" target="_blank">Jinja2</a> templating, secure cookies, <a href="https://en.wikipedia.org/wiki/Unit_testing" class="external" target="_blank">unit testing</a>, and <a href="https://restapitutorial.com/" class="external" target="_blank">RESTful</a> request dispatching. It has good documentation and an active community.</p> <p>Flask has become extremely popular, particularly for developers who need to provide web services on small, resource-constrained systems (e.g. running a web server on a <a href="https://www.raspberrypi.org/" class="external" target="_blank">Raspberry Pi</a>, <a href="https://www.techuseful.com/drone-definitions-learning-the-drone-lingo/" class="external" target="_blank">Drone controllers</a>, etc.)</p></div></section><section aria-labelledby="express_node.jsjavascript"><h3 id="express_node.jsjavascript"><a href="#express_node.jsjavascript">Express (Node.js/JavaScript)</a></h3><div class="section-content"><p><a href="https://expressjs.com/" class="external" target="_blank">Express</a> is a fast, unopinionated, flexible and minimalist web framework for <a href="https://nodejs.org/en/" class="external" target="_blank">Node.js</a> (node is a browserless environment for running JavaScript). It provides a robust set of features for web and mobile applications and delivers useful HTTP utility methods and <a href="/en-US/docs/Glossary/Middleware">middleware</a>.</p> <p>Express is extremely popular, partially because it eases the migration of client-side JavaScript web programmers into server-side development, and partially because it is resource-efficient (the underlying node environment uses lightweight multitasking within a thread rather than spawning separate processes for every new web request).</p> <p>Because Express is a minimalist web framework it does not incorporate every component that you might want to use (for example, database access and support for users and sessions are provided through independent libraries). There are many excellent independent components, but sometimes it can be hard to work out which is the best for a particular purpose!</p> <p>Many popular server-side and full stack frameworks (comprising both server and client-side frameworks) are based on Express, including <a href="https://feathersjs.com/" class="external" target="_blank">Feathers</a>, <a href="https://itemsapi.com/" class="external" target="_blank">ItemsAPI</a>, <a href="https://keystonejs.com/" class="external" target="_blank">KeystoneJS</a>, <a href="https://krakenjs.com/" class="external" target="_blank">Kraken</a>, <a href="https://loopback.io/" class="external" target="_blank">LoopBack</a>, <a href="https://github.com/linnovate/mean" class="external" target="_blank">MEAN</a>, and <a href="https://sailsjs.com/" class="external" target="_blank">Sails</a>.</p> <p>A lot of high profile companies use Express, including: Uber, Accenture, IBM, etc.</p></div></section><section aria-labelledby="deno_javascript"><h3 id="deno_javascript"><a href="#deno_javascript">Deno (JavaScript)</a></h3><div class="section-content"><p><a href="https://deno.com/" class="external" target="_blank">Deno</a> is a simple, modern, and secure <a href="/en-US/docs/Web/JavaScript">JavaScript</a>/TypeScript runtime and framework built on top of Chrome V8 and <a href="https://www.rust-lang.org/" class="external" target="_blank">Rust</a>.</p> <p>Deno is powered by <a href="https://tokio.rs/" class="external" target="_blank">Tokio</a> — a Rust-based asynchronous runtime which lets it serve web pages faster. It also has internal support for <a href="/en-US/docs/WebAssembly">WebAssembly</a>, which enables the compilation of binary code for use on the client-side. Deno aims to fill in some of the loop-holes in <a href="/en-US/docs/Learn/Server-side/Node_server_without_framework">Node.js</a> by providing a mechanism that naturally maintains better security.</p> <p>Deno's features include:</p> <ul> <li>Security by default. <a href="https://docs.deno.com/runtime/fundamentals/security/" class="external" target="_blank">Deno modules restrict permissions</a> to <strong>file</strong>, <strong>network</strong>, or <strong>environment</strong> access unless explicitly allowed.</li> <li>TypeScript support <strong>out-of-the-box</strong>.</li> <li>First-class await mechanism.</li> <li>Built-in testing facility and code formatter (<code>deno fmt</code>)</li> <li>(JavaScript) Browser compatibility: Deno programs that are written completely in JavaScript excluding the <code>Deno</code> namespace (or feature test for it), should work directly in any modern browser.</li> <li>Script bundling into a single JavaScript file.</li> </ul> <p>Deno provides an easy yet powerful way to use JavaScript for both client- and server-side programming.</p></div></section><section aria-labelledby="ruby_on_rails_ruby"><h3 id="ruby_on_rails_ruby"><a href="#ruby_on_rails_ruby">Ruby on Rails (Ruby)</a></h3><div class="section-content"><p><a href="https://rubyonrails.org/" class="external" target="_blank">Rails</a> (usually referred to as "Ruby on Rails") is a web framework written for the Ruby programming language.</p> <p>Rails follows a very similar design philosophy to Django. Like Django it provides standard mechanisms for routing URLs, accessing data from a database, generating HTML from templates and formatting data as <a href="/en-US/docs/Glossary/JSON">JSON</a> or <a href="/en-US/docs/Glossary/XML">XML</a>. It similarly encourages the use of design patterns like DRY ("don't repeat yourself" — write code only once if at all possible), MVC (model-view-controller) and a number of others.</p> <p>There are of course many differences due to specific design decisions and the nature of the languages.</p> <p>Rails has been used for high profile sites, including: <a href="https://basecamp.com/" class="external" target="_blank">Basecamp</a>, <a href="https://github.com/" class="external" target="_blank">GitHub</a>, <a href="https://www.shopify.com/" class="external" target="_blank">Shopify</a>, <a href="https://www.airbnb.com/" class="external" target="_blank">Airbnb</a>, <a href="https://www.twitch.tv/" class="external" target="_blank">Twitch</a>, <a href="https://soundcloud.com/" class="external" target="_blank">SoundCloud</a>, <a href="https://www.hulu.com/welcome" class="external" target="_blank">Hulu</a>, <a href="https://www.zendesk.com/" class="external" target="_blank">Zendesk</a>, <a href="https://squareup.com/us/en" class="external" target="_blank">Square</a>, <a href="https://highrisehq.com/" class="external" target="_blank">Highrise</a>.</p></div></section><section aria-labelledby="laravel_php"><h3 id="laravel_php"><a href="#laravel_php">Laravel (PHP)</a></h3><div class="section-content"><p><a href="https://laravel.com/" class="external" target="_blank">Laravel</a> is a web application framework with expressive, elegant syntax. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as:</p> <ul> <li><a href="https://laravel.com/docs/routing" class="external" target="_blank">Simple, fast routing engine</a>.</li> <li><a href="https://laravel.com/docs/container" class="external" target="_blank">Powerful dependency injection container</a>.</li> <li>Multiple back-ends for <a href="https://laravel.com/docs/session" class="external" target="_blank">session</a> and <a href="https://laravel.com/docs/cache" class="external" target="_blank">cache</a> storage.</li> <li>Expressive, intuitive <a href="https://laravel.com/docs/eloquent" class="external" target="_blank">database ORM</a>.</li> <li>Database agnostic <a href="https://laravel.com/docs/migrations" class="external" target="_blank">schema migrations</a>.</li> <li><a href="https://laravel.com/docs/queues" class="external" target="_blank">Robust background job processing</a>.</li> <li><a href="https://laravel.com/docs/broadcasting" class="external" target="_blank">Real-time event broadcasting</a>.</li> </ul> <p>Laravel is accessible, yet powerful, providing tools needed for large, robust applications.</p></div></section><section aria-labelledby="asp.net"><h3 id="asp.net"><a href="#asp.net">ASP.NET</a></h3><div class="section-content"><p><a href="https://dotnet.microsoft.com/en-us/apps/aspnet" class="external" target="_blank">ASP.NET</a> is an open source web framework developed by Microsoft for building modern web applications and services. With ASP.NET you can quickly create websites based on HTML, CSS, and JavaScript, scale them for use by millions of users and easily add more complex capabilities like Web APIs, forms over data, or real time communications.</p> <p>One of the differentiators for ASP.NET is that it is built on the <a href="https://en.wikipedia.org/wiki/Common_Language_Runtime" class="external" target="_blank">Common Language Runtime</a> (CLR), allowing programmers to write ASP.NET code using any supported .NET language (C#, Visual Basic, etc.). Like many Microsoft products it benefits from excellent tools (often free), an active developer community, and well-written documentation.</p> <p>ASP.NET is used by Microsoft, Xbox.com, Stack Overflow, and many others.</p></div></section><section aria-labelledby="mojolicious_perl"><h3 id="mojolicious_perl"><a href="#mojolicious_perl">Mojolicious (Perl)</a></h3><div class="section-content"><p><a href="https://mojolicious.org/" class="external" target="_blank">Mojolicious</a> is a next-generation web framework for the Perl programming language.</p> <p>Back in the early days of the web, many people learned Perl because of a wonderful Perl library called <a href="https://metacpan.org/pod/CGI" class="external" target="_blank">CGI</a>. It was simple enough to get started without knowing much about the language and powerful enough to keep you going. Mojolicious implements this idea using bleeding edge technologies.</p> <p>Some of the features provided by Mojolicious are:</p> <ul> <li>A real-time web framework, to easily grow single-file prototypes into well-structured MVC web applications.</li> <li>RESTful routes, plugins, commands, Perl-ish templates, content negotiation, session management, form validation, testing framework, static file server, CGI/<a href="https://plackperl.org/" class="external" target="_blank">PSGI</a> detection, and first-class Unicode support.</li> <li>A full-stack HTTP and WebSocket client/server implementation with IPv6, TLS, SNI, IDNA, HTTP/SOCKS5 proxy, UNIX domain socket, Comet (long polling), keep-alive, connection pooling, timeout, cookie, multipart, and gzip compression support.</li> <li>JSON and HTML/XML parsers and generators with CSS selector support.</li> <li>Very clean, portable and object-oriented pure-Perl API with no hidden magic.</li> <li>Fresh code based upon years of experience, free and open-source.</li> </ul></div></section><section aria-labelledby="spring_boot_java"><h3 id="spring_boot_java"><a href="#spring_boot_java">Spring Boot (Java)</a></h3><div class="section-content"><p><a href="https://spring.io/projects/spring-boot/" class="external" target="_blank">Spring Boot</a> is one of a number of projects provided by <a href="https://spring.io/" class="external" target="_blank">Spring</a>. It is a good starting point for doing server-side web development using <a href="https://www.java.com/" class="external" target="_blank">Java</a>.</p> <p>Although definitely not the only framework based on <a href="https://www.java.com/" class="external" target="_blank">Java</a> it is easy to use to create stand-alone, production-grade Spring-based Applications that you can "just run". It is an opinionated view of the Spring platform and third-party libraries but allows to start with minimum fuss and configuration.</p> <p>It can be used for small problems but its strength is building larger scale applications that use a cloud approach. Usually multiple applications run in parallel talking to each other, with some providing user interaction and others doing back end work (e.g. accessing databases or other services). Load balancers help to ensure redundancy and reliability or allow geolocated handling of user requests to ensure responsiveness.</p></div></section><section aria-labelledby="summary"><h2 id="summary"><a href="#summary">Summary</a></h2><div class="section-content"><p>This article has shown that web frameworks can make it easier to develop and maintain server-side code. It has also provided a high level overview of a few popular frameworks, and discussed criteria for choosing a web application framework. You should now have at least an idea of how to choose a web framework for your own server-side development. If not, then don't worry — later on in the course we'll give you detailed tutorials on Django and Express to give you some experience of actually working with a web framework.</p> <p>For the next article in this module we'll change direction slightly and consider web security.</p><ul class="prev-next"> <li><a class="button secondary" href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview"><span class="button-wrap"> Previous </span></a></li> <li><a class="button secondary" href="/en-US/docs/Learn/Server-side/First_steps"><span class="button-wrap"> Overview: Server-side website programming first steps</span></a></li> <li><a class="button secondary" href="/en-US/docs/Learn/Server-side/First_steps/Website_security"><span class="button-wrap"> Next </span></a></li> </ul></div></section></article><aside class="article-footer"><div class="article-footer-inner"><div class="svg-container"><svg xmlns="http://www.w3.org/2000/svg" width="162" height="162" viewBox="0 0 162 162" fill="none" role="none"><mask id="b" fill="#fff"><path d="M97.203 47.04c8.113-7.886 18.004-13.871 28.906-17.492a78 78 0 0 1 33.969-3.39c11.443 1.39 22.401 5.295 32.024 11.411s17.656 14.28 23.476 23.86c5.819 9.579 9.269 20.318 10.083 31.385a69.85 69.85 0 0 1-5.387 32.44c-4.358 10.272-11.115 19.443-19.747 26.801-8.632 7.359-18.908 12.709-30.034 15.637l-6.17-21.698c7.666-2.017 14.746-5.703 20.694-10.773 5.948-5.071 10.603-11.389 13.606-18.467a48.14 48.14 0 0 0 3.712-22.352c-.561-7.625-2.938-15.025-6.948-21.625s-9.544-12.226-16.175-16.44-14.181-6.904-22.065-7.863a53.75 53.75 0 0 0-23.405 2.336c-7.513 2.495-14.327 6.62-19.918 12.053z"></path></mask><path stroke="url(#a)" stroke-dasharray="6, 6" stroke-width="2" d="M97.203 47.04c8.113-7.886 18.004-13.871 28.906-17.492a78 78 0 0 1 33.969-3.39c11.443 1.39 22.401 5.295 32.024 11.411s17.656 14.28 23.476 23.86c5.819 9.579 9.269 20.318 10.083 31.385a69.85 69.85 0 0 1-5.387 32.44c-4.358 10.272-11.115 19.443-19.747 26.801-8.632 7.359-18.908 12.709-30.034 15.637l-6.17-21.698c7.666-2.017 14.746-5.703 20.694-10.773 5.948-5.071 10.603-11.389 13.606-18.467a48.14 48.14 0 0 0 3.712-22.352c-.561-7.625-2.938-15.025-6.948-21.625s-9.544-12.226-16.175-16.44-14.181-6.904-22.065-7.863a53.75 53.75 0 0 0-23.405 2.336c-7.513 2.495-14.327 6.62-19.918 12.053z" mask="url(#b)" style="stroke:url(#a)" transform="translate(-63.992 -25.587)"></path><ellipse cx="8.066" cy="111.597" fill="var(--background-tertiary)" rx="53.677" ry="53.699" transform="matrix(.71707 -.697 .7243 .6895 0 0)"></ellipse><g clip-path="url(#c)" transform="translate(-63.992 -25.587)"><path fill="#9abff5" d="m144.256 137.379 32.906 12.434a4.41 4.41 0 0 1 2.559 5.667l-9.326 24.679a4.41 4.41 0 0 1-5.667 2.559l-8.226-3.108-2.332 6.17c-.466 1.233-.375 1.883-1.609 1.417l-2.253-.527c-.411-.155-.95-.594-1.206-1.161l-4.734-10.484-12.545-4.741a4.41 4.41 0 0 1-2.559-5.667l9.325-24.679a4.41 4.41 0 0 1 5.667-2.559m9.961 29.617 8.227 3.108 3.264-8.638-.498-6.768-4.113-1.555.548 7.258-4.319-1.632zm-12.339-4.663 8.226 3.108 3.264-8.637-.498-6.769-4.113-1.554.548 7.257-4.319-1.632z"></path></g><g clip-path="url(#d)" transform="translate(-63.992 -25.587)"><path fill="#81b0f3" d="M135.35 60.136 86.67 41.654c-3.346-1.27-7.124.428-8.394 3.775L64.414 81.938c-1.27 3.347.428 7.125 3.774 8.395l12.17 4.62-3.465 9.128c-.693 1.826-1.432 2.457.394 3.15l3.014 1.625c.609.231 1.637.274 2.477-.104l15.53-6.983 18.56 7.047c3.346 1.27 7.124-.428 8.395-3.775l13.862-36.51c1.27-3.346-.428-7.124-3.775-8.395M95.261 83.207l-12.17-4.62 4.852-12.779 7.19-7.017 6.085 2.31-7.725 7.51 6.389 2.426zm18.255 6.93-12.17-4.62 4.852-12.778 7.189-7.017 6.085 2.31-7.725 7.51 6.39 2.426z"></path></g><defs><clipPath id="c"><path fill="#fff" d="m198.638 146.586-65.056-24.583-24.583 65.057 65.056 24.582z"></path></clipPath><clipPath id="d"><path fill="#fff" d="m66.438 14.055 96.242 36.54-36.54 96.243-96.243-36.54z"></path></clipPath><linearGradient id="a" x1="97.203" x2="199.995" y1="47.04" y2="152.793" gradientUnits="userSpaceOnUse"><stop stop-color="#086DFC"></stop><stop offset="0.246" stop-color="#2C81FA"></stop><stop offset="0.516" stop-color="#5497F8"></stop><stop offset="0.821" stop-color="#80B0F6"></stop><stop offset="1" stop-color="#9ABFF5"></stop></linearGradient></defs></svg></div><h2>Help improve MDN</h2><fieldset class="feedback"><label>Was this page helpful to you?</label><div class="button-container"><button type="button" class="button primary has-icon yes"><span class="button-wrap"><span class="icon icon-thumbs-up "></span>Yes</span></button><button type="button" class="button primary has-icon no"><span class="button-wrap"><span class="icon icon-thumbs-down "></span>No</span></button></div></fieldset><a class="contribute" href="https://github.com/mdn/content/blob/main/CONTRIBUTING.md" title="This will take you to our contribution guidelines on GitHub." target="_blank" rel="noopener noreferrer">Learn how to contribute</a>.<p class="last-modified-date">This page was last modified on<!-- --> <time dateTime="2024-10-31T19:44:02.000Z">Oct 31, 2024</time> by<!-- --> <a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks/contributors.txt" rel="nofollow">MDN contributors</a>.</p><div id="on-github" class="on-github"><a href="https://github.com/mdn/content/blob/main/files/en-us/learn/server-side/first_steps/web_frameworks/index.md?plain=1" title="Folder: en-us/learn/server-side/first_steps/web_frameworks (Opens in a new tab)" target="_blank" rel="noopener noreferrer">View this page on GitHub</a> <!-- -->•<!-- --> <a href="https://github.com/mdn/content/issues/new?template=page-report.yml&mdn-url=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FLearn%2FServer-side%2FFirst_steps%2FWeb_frameworks&metadata=%3C%21--+Do+not+make+changes+below+this+line+--%3E%0A%3Cdetails%3E%0A%3Csummary%3EPage+report+details%3C%2Fsummary%3E%0A%0A*+Folder%3A+%60en-us%2Flearn%2Fserver-side%2Ffirst_steps%2Fweb_frameworks%60%0A*+MDN+URL%3A+https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FLearn%2FServer-side%2FFirst_steps%2FWeb_frameworks%0A*+GitHub+URL%3A+https%3A%2F%2Fgithub.com%2Fmdn%2Fcontent%2Fblob%2Fmain%2Ffiles%2Fen-us%2Flearn%2Fserver-side%2Ffirst_steps%2Fweb_frameworks%2Findex.md%0A*+Last+commit%3A+https%3A%2F%2Fgithub.com%2Fmdn%2Fcontent%2Fcommit%2F41a27d6c0f8e44f1b9a3dabddd9315655b367b77%0A*+Document+last+modified%3A+2024-10-31T19%3A44%3A02.000Z%0A%0A%3C%2Fdetails%3E" title="This will take you to GitHub to file a new issue." target="_blank" rel="noopener noreferrer">Report a problem with this content</a></div></div></aside></main></div></div><footer id="nav-footer" class="page-footer"><div class="page-footer-grid"><div class="page-footer-logo-col"><a href="/" class="mdn-footer-logo" aria-label="MDN homepage"><svg width="48" height="17" viewBox="0 0 48 17" fill="none" xmlns="http://www.w3.org/2000/svg"><title id="mdn-footer-logo-svg">MDN logo</title><path d="M20.04 16.512H15.504V10.416C15.504 9.488 15.344 8.824 15.024 8.424C14.72 8.024 14.264 7.824 13.656 7.824C12.92 7.824 12.384 8.064 12.048 8.544C11.728 9.024 11.568 9.64 11.568 10.392V14.184H13.008V16.512H8.472V10.416C8.472 9.488 8.312 8.824 7.992 8.424C7.688 8.024 7.232 7.824 6.624 7.824C5.872 7.824 5.336 8.064 5.016 8.544C4.696 9.024 4.536 9.64 4.536 10.392V14.184H6.6V16.512H0V14.184H1.44V8.04H0.024V5.688H4.536V7.32C5.224 6.088 6.32 5.472 7.824 5.472C8.608 5.472 9.328 5.664 9.984 6.048C10.64 6.432 11.096 7.016 11.352 7.8C11.992 6.248 13.168 5.472 14.88 5.472C15.856 5.472 16.72 5.776 17.472 6.384C18.224 6.992 18.6 7.936 18.6 9.216V14.184H20.04V16.512Z" fill="currentColor"></path><path d="M33.6714 16.512H29.1354V14.496C28.8314 15.12 28.3834 15.656 27.7914 16.104C27.1994 16.536 26.4154 16.752 25.4394 16.752C24.0154 16.752 22.8954 16.264 22.0794 15.288C21.2634 14.312 20.8554 12.984 20.8554 11.304C20.8554 9.688 21.2554 8.312 22.0554 7.176C22.8554 6.04 24.0634 5.472 25.6794 5.472C26.5594 5.472 27.2794 5.648 27.8394 6C28.3994 6.352 28.8314 6.8 29.1354 7.344V2.352H26.9754V0H32.2314V14.184H33.6714V16.512ZM29.1354 11.04V10.776C29.1354 9.88 28.8954 9.184 28.4154 8.688C27.9514 8.176 27.3674 7.92 26.6634 7.92C25.9754 7.92 25.3674 8.176 24.8394 8.688C24.3274 9.2 24.0714 10.008 24.0714 11.112C24.0714 12.152 24.3114 12.944 24.7914 13.488C25.2714 14.032 25.8394 14.304 26.4954 14.304C27.3114 14.304 27.9514 13.96 28.4154 13.272C28.8954 12.584 29.1354 11.84 29.1354 11.04Z" fill="currentColor"></path><path d="M47.9589 16.512H41.9829V14.184H43.4229V10.416C43.4229 9.488 43.2629 8.824 42.9429 8.424C42.6389 8.024 42.1829 7.824 41.5749 7.824C40.8389 7.824 40.2709 8.056 39.8709 8.52C39.4709 8.968 39.2629 9.56 39.2469 10.296V14.184H40.6869V16.512H34.7109V14.184H36.1509V8.04H34.5909V5.688H39.2469V7.344C39.9669 6.096 41.1269 5.472 42.7269 5.472C43.7509 5.472 44.6389 5.776 45.3909 6.384C46.1429 6.992 46.5189 7.936 46.5189 9.216V14.184H47.9589V16.512Z" fill="currentColor"></path></svg></a><p>Your blueprint for a better internet.</p><ul class="social-icons"><li><a href="https://mozilla.social/@mdn" target="_blank" rel="me noopener noreferrer"><span class="icon icon-mastodon"></span><span class="visually-hidden">MDN on Mastodon</span></a></li><li><a href="https://twitter.com/mozdevnet" target="_blank" rel="noopener noreferrer"><span class="icon icon-twitter-x"></span><span class="visually-hidden">MDN on X (formerly Twitter)</span></a></li><li><a href="https://github.com/mdn/" target="_blank" rel="noopener noreferrer"><span class="icon icon-github-mark-small"></span><span class="visually-hidden">MDN on GitHub</span></a></li><li><a href="/en-US/blog/rss.xml" target="_blank"><span class="icon icon-feed"></span><span class="visually-hidden">MDN Blog RSS Feed</span></a></li></ul></div><div class="page-footer-nav-col-1"><h2 class="footer-nav-heading">MDN</h2><ul class="footer-nav-list"><li class="footer-nav-item"><a href="/en-US/about">About</a></li><li class="footer-nav-item"><a href="/en-US/blog/">Blog</a></li><li class="footer-nav-item"><a href="https://www.mozilla.org/en-US/careers/listings/?team=ProdOps" target="_blank" rel="noopener noreferrer">Careers</a></li><li class="footer-nav-item"><a href="/en-US/advertising">Advertise with us</a></li></ul></div><div class="page-footer-nav-col-2"><h2 class="footer-nav-heading">Support</h2><ul class="footer-nav-list"><li class="footer-nav-item"><a class="footer-nav-link" href="https://support.mozilla.org/products/mdn-plus">Product help</a></li><li class="footer-nav-item"><a class="footer-nav-link" href="/en-US/docs/MDN/Community/Issues">Report an issue</a></li></ul></div><div class="page-footer-nav-col-3"><h2 class="footer-nav-heading">Our communities</h2><ul class="footer-nav-list"><li class="footer-nav-item"><a class="footer-nav-link" href="/en-US/community">MDN Community</a></li><li class="footer-nav-item"><a class="footer-nav-link" href="https://discourse.mozilla.org/c/mdn/236" target="_blank" rel="noopener noreferrer">MDN Forum</a></li><li class="footer-nav-item"><a class="footer-nav-link" href="/discord" target="_blank" rel="noopener noreferrer">MDN Chat</a></li></ul></div><div class="page-footer-nav-col-4"><h2 class="footer-nav-heading">Developers</h2><ul class="footer-nav-list"><li class="footer-nav-item"><a class="footer-nav-link" href="/en-US/docs/Web">Web Technologies</a></li><li class="footer-nav-item"><a class="footer-nav-link" href="/en-US/docs/Learn">Learn Web Development</a></li><li class="footer-nav-item"><a class="footer-nav-link" href="/en-US/plus">MDN Plus</a></li><li class="footer-nav-item"><a href="https://hacks.mozilla.org/" target="_blank" rel="noopener noreferrer">Hacks Blog</a></li></ul></div><div class="page-footer-moz"><a href="https://www.mozilla.org/" class="footer-moz-logo-link" target="_blank" rel="noopener noreferrer"><svg width="112" height="32" fill="none" xmlns="http://www.w3.org/2000/svg"><title id="mozilla-footer-logo-svg">Mozilla logo</title><path d="M41.753 14.218c-2.048 0-3.324 1.522-3.324 4.157 0 2.423 1.119 4.286 3.29 4.286 2.082 0 3.447-1.678 3.447-4.347 0-2.826-1.522-4.096-3.413-4.096Zm54.89 7.044c0 .901.437 1.618 1.645 1.618 1.427 0 2.949-1.024 3.044-3.352-.649-.095-1.365-.185-2.02-.185-1.426-.005-2.668.397-2.668 1.92Z" fill="currentColor"></path><path d="M0 0v32h111.908V0H0Zm32.56 25.426h-5.87v-7.884c0-2.423-.806-3.352-2.39-3.352-1.924 0-2.702 1.365-2.702 3.324v4.868h1.864v3.044h-5.864v-7.884c0-2.423-.806-3.352-2.39-3.352-1.924 0-2.702 1.365-2.702 3.324v4.868h2.669v3.044H6.642v-3.044h1.863v-7.918H6.642V11.42h5.864v2.11c.839-1.489 2.3-2.39 4.252-2.39 2.02 0 3.878.963 4.566 3.01.778-1.862 2.361-3.01 4.566-3.01 2.512 0 4.812 1.522 4.812 4.84v6.402h1.863v3.044h-.005Zm9.036.307c-4.314 0-7.296-2.635-7.296-7.106 0-4.096 2.484-7.481 7.514-7.481s7.481 3.38 7.481 7.29c0 4.472-3.228 7.297-7.699 7.297Zm22.578-.307H51.942l-.403-2.11 7.7-8.846h-4.376l-.621 2.17-2.888-.313.498-4.907h12.294l.313 2.11-7.767 8.852h4.533l.654-2.172 3.167.308-.872 4.908Zm7.99 0h-4.191v-5.03h4.19v5.03Zm0-8.976h-4.191v-5.03h4.19v5.03Zm2.618 8.976 6.054-21.358h3.945l-6.054 21.358h-3.945Zm8.136 0 6.048-21.358h3.945l-6.054 21.358h-3.939Zm21.486.307c-1.863 0-2.887-1.085-3.072-2.792-.805 1.427-2.232 2.792-4.498 2.792-2.02 0-4.314-1.085-4.314-4.006 0-3.447 3.323-4.253 6.518-4.253.778 0 1.584.034 2.3.124v-.465c0-1.427-.034-3.133-2.3-3.133-.84 0-1.488.061-2.143.402l-.453 1.578-3.195-.34.549-3.224c2.45-.996 3.692-1.27 5.992-1.27 3.01 0 5.556 1.55 5.556 4.75v6.083c0 .805.314 1.085.963 1.085.184 0 .375-.034.587-.095l.034 2.11a5.432 5.432 0 0 1-2.524.654Z" fill="currentColor"></path></svg></a><ul class="footer-moz-list"><li class="footer-moz-item"><a href="https://www.mozilla.org/privacy/websites/" class="footer-moz-link" target="_blank" rel="noopener noreferrer">Website Privacy Notice</a></li><li class="footer-moz-item"><a href="https://www.mozilla.org/privacy/websites/#cookies" class="footer-moz-link" target="_blank" rel="noopener noreferrer">Cookies</a></li><li class="footer-moz-item"><a href="https://www.mozilla.org/about/legal/terms/mozilla" class="footer-moz-link" target="_blank" rel="noopener noreferrer">Legal</a></li><li class="footer-moz-item"><a href="https://www.mozilla.org/about/governance/policies/participation/" class="footer-moz-link" target="_blank" rel="noopener noreferrer">Community Participation Guidelines</a></li></ul></div><div class="page-footer-legal"><p id="license" class="page-footer-legal-text">Visit<!-- --> <a href="https://www.mozilla.org" target="_blank" rel="noopener noreferrer">Mozilla Corporation’s</a> <!-- -->not-for-profit parent, the<!-- --> <a target="_blank" rel="noopener noreferrer" href="https://foundation.mozilla.org/">Mozilla Foundation</a>.<br/>Portions of this content are ©1998–<!-- -->2024<!-- --> by individual mozilla.org contributors. Content available under<!-- --> <a href="/en-US/docs/MDN/Writing_guidelines/Attrib_copyright_license">a Creative Commons license</a>.</p></div></div></footer></div><script type="application/json" id="hydration">{"url":"/en-US/docs/Learn/Server-side/First_steps/Web_frameworks","doc":{"isMarkdown":true,"isTranslated":false,"isActive":true,"flaws":{},"title":"Server-side web frameworks","mdn_url":"/en-US/docs/Learn/Server-side/First_steps/Web_frameworks","locale":"en-US","native":"English (US)","sidebarHTML":"<ol><li class=\"section\"><a href=\"/en-US/docs/Learn/Getting_started_with_the_web\">Complete beginners start here!</a></li><li><details><summary>Getting started with the web</summary><ol><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web\">Getting started with the web</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/Installing_basic_software\">Installing basic software</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/What_will_your_website_look_like\">What will your website look like?</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/Dealing_with_files\">Dealing with files</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/HTML_basics\">HTML basics</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics\">CSS basics</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics\">JavaScript basics</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/Publishing_your_website\">Publishing your website</a></li><li><a href=\"/en-US/docs/Learn/Getting_started_with_the_web/How_the_Web_works\">How the web works</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/HTML\">HTML — Structuring the web</a></li><li><details><summary>Introduction to HTML</summary><ol><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML\">Introduction to HTML</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started\">Getting started with HTML</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML\">What's in the head? Metadata in HTML</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals\">HTML text fundamentals</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks\">Creating hyperlinks</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/Advanced_text_formatting\">Advanced text formatting</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure\">Document and website structure</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/Debugging_HTML\">Debugging HTML</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/Marking_up_a_letter\">Marking up a letter</a></li><li><a href=\"/en-US/docs/Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content\">Structuring a page of content</a></li></ol></details></li><li><details><summary>Multimedia and embedding</summary><ol><li><a href=\"/en-US/docs/Learn/HTML/Multimedia_and_embedding\">Multimedia and embedding</a></li><li><a href=\"/en-US/docs/Learn/HTML/Multimedia_and_embedding/Images_in_HTML\">Images in HTML</a></li><li><a href=\"/en-US/docs/Learn/HTML/Multimedia_and_embedding/Video_and_audio_content\">Video and audio content</a></li><li><a href=\"/en-US/docs/Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies\">From object to iframe — other embedding technologies</a></li><li><a href=\"/en-US/docs/Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web\">Adding vector graphics to the web</a></li><li><a href=\"/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images\">Responsive images</a></li><li><a href=\"/en-US/docs/Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page\">Mozilla splash page</a></li></ol></details></li><li><details><summary>HTML tables</summary><ol><li><a href=\"/en-US/docs/Learn/HTML/Tables\">HTML tables</a></li><li><a href=\"/en-US/docs/Learn/HTML/Tables/Basics\">HTML table basics</a></li><li><a href=\"/en-US/docs/Learn/HTML/Tables/Advanced\">HTML table advanced features and accessibility</a></li><li><a href=\"/en-US/docs/Learn/HTML/Tables/Structuring_planet_data\">Structuring planet data</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/CSS\">CSS — Styling the web</a></li><li><details><summary>CSS first steps</summary><ol><li><a href=\"/en-US/docs/Learn/CSS/First_steps\">CSS first steps</a></li><li><a href=\"/en-US/docs/Learn/CSS/First_steps/What_is_CSS\">What is CSS?</a></li><li><a href=\"/en-US/docs/Learn/CSS/First_steps/Getting_started\">Getting started with CSS</a></li><li><a href=\"/en-US/docs/Learn/CSS/First_steps/How_CSS_is_structured\">How CSS is structured</a></li><li><a href=\"/en-US/docs/Learn/CSS/First_steps/How_CSS_works\">How CSS works</a></li><li><a href=\"/en-US/docs/Learn/CSS/First_steps/Styling_a_biography_page\">Styling a biography page</a></li></ol></details></li><li><details><summary>CSS building blocks</summary><ol><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks\">CSS building blocks</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Selectors\">CSS selectors</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors\">Type, class, and ID selectors</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Selectors/Attribute_selectors\">Attribute selectors</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements\">Pseudo-classes and pseudo-elements</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators\">Combinators</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance\">Cascade, specificity, and inheritance</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers\">Cascade layers</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/The_box_model\">The box model</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Backgrounds_and_borders\">Backgrounds and borders</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Handling_different_text_directions\">Handling different text directions</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Overflowing_content\">Overflowing content</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Values_and_units\">CSS values and units</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Sizing_items_in_CSS\">Sizing items in CSS</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Images_media_form_elements\">Images, media, and form elements</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Styling_tables\">Styling tables</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Advanced_styling_effects\">Advanced styling effects</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Debugging_CSS\">Debugging CSS</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Organizing\">Organizing your CSS</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Fundamental_CSS_comprehension\">Fundamental CSS comprehension</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper\">Creating fancy letterheaded paper</a></li><li><a href=\"/en-US/docs/Learn/CSS/Building_blocks/A_cool_looking_box\">A cool-looking box</a></li></ol></details></li><li><details><summary>Styling text</summary><ol><li><a href=\"/en-US/docs/Learn/CSS/Styling_text\">CSS styling text</a></li><li><a href=\"/en-US/docs/Learn/CSS/Styling_text/Fundamentals\">Fundamental text and font styling</a></li><li><a href=\"/en-US/docs/Learn/CSS/Styling_text/Styling_lists\">Styling lists</a></li><li><a href=\"/en-US/docs/Learn/CSS/Styling_text/Styling_links\">Styling links</a></li><li><a href=\"/en-US/docs/Learn/CSS/Styling_text/Web_fonts\">Web fonts</a></li><li><a href=\"/en-US/docs/Learn/CSS/Styling_text/Typesetting_a_homepage\">Typesetting a community school homepage</a></li></ol></details></li><li><details><summary>CSS layout</summary><ol><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout\">CSS layout</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Introduction\">Introduction to CSS layout</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Normal_Flow\">Normal Flow</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Flexbox\">Flexbox</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Grids\">Grids</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Floats\">Floats</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Positioning\">Positioning</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Multiple-column_Layout\">Multiple-column layout</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design\">Responsive design</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Media_queries\">Beginner's guide to media queries</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Legacy_Layout_Methods\">Legacy layout methods</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Supporting_Older_Browsers\">Supporting older browsers</a></li><li><a href=\"/en-US/docs/Learn/CSS/CSS_layout/Fundamental_Layout_Comprehension\">Fundamental layout comprehension</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/JavaScript\">JavaScript — Dynamic client-side scripting</a></li><li><details><summary>JavaScript first steps</summary><ol><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps\">JavaScript first steps</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript\">What is JavaScript?</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/A_first_splash\">A first splash into JavaScript</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong\">What went wrong? Troubleshooting JavaScript</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/Variables\">Storing the information you need — Variables</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/Math\">Basic math in JavaScript — numbers and operators</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/Strings\">Handling text — strings in JavaScript</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods\">Useful string methods</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/Arrays\">Arrays</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator\">Silly story generator</a></li></ol></details></li><li><details><summary>JavaScript building blocks</summary><ol><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks\">JavaScript building blocks</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/conditionals\">Making decisions in your code — conditionals</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code\">Looping code</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/Functions\">Functions — reusable blocks of code</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function\">Build your own function</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/Return_values\">Function return values</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/Events\">Introduction to events</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/Event_bubbling\">Event bubbling</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery\">Image gallery</a></li></ol></details></li><li><details><summary>Introducing JavaScript objects</summary><ol><li><a href=\"/en-US/docs/Learn/JavaScript/Objects\">Introducing JavaScript objects</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Objects/Basics\">JavaScript object basics</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Objects/Object_prototypes\">Object prototypes</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Objects/Object-oriented_programming\">Object-oriented programming</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript\">Classes in JavaScript</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Objects/JSON\">Working with JSON</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Objects/Object_building_practice\">Object building practice</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features\">Adding features to our bouncing balls demo</a></li></ol></details></li><li><details><summary>Asynchronous JavaScript</summary><ol><li><a href=\"/en-US/docs/Learn/JavaScript/Asynchronous\">Asynchronous JavaScript</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Asynchronous/Introducing\">Introducing asynchronous JavaScript</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Asynchronous/Promises\">How to use promises</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Asynchronous/Implementing_a_promise-based_API\">How to implement a promise-based API</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Asynchronous/Introducing_workers\">Introducing workers</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Asynchronous/Sequencing_animations\">Sequencing animations</a></li></ol></details></li><li><details><summary>Client-side web APIs</summary><ol><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs\">Client-side web APIs</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction\">Introduction to web APIs</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents\">Manipulating documents</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data\">Fetching data from the server</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs\">Third-party APIs</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics\">Drawing graphics</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs\">Video and Audio APIs</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage\">Client-side storage</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/Forms\">Web forms — Working with user data</a></li><li><details><summary>Web form building blocks</summary><ol><li><a href=\"/en-US/docs/Learn/Forms\">Web form building blocks</a></li><li><a href=\"/en-US/docs/Learn/Forms/Your_first_form\">Your first form</a></li><li><a href=\"/en-US/docs/Learn/Forms/How_to_structure_a_web_form\">How to structure a web form</a></li><li><a href=\"/en-US/docs/Learn/Forms/Basic_native_form_controls\">Basic native form controls</a></li><li><a href=\"/en-US/docs/Learn/Forms/HTML5_input_types\">The HTML5 input types</a></li><li><a href=\"/en-US/docs/Learn/Forms/Other_form_controls\">Other form controls</a></li><li><a href=\"/en-US/docs/Learn/Forms/Styling_web_forms\">Styling web forms</a></li><li><a href=\"/en-US/docs/Learn/Forms/Advanced_form_styling\">Advanced form styling</a></li><li><a href=\"/en-US/docs/Learn/Forms/UI_pseudo-classes\">UI pseudo-classes</a></li><li><a href=\"/en-US/docs/Learn/Forms/Form_validation\">Client-side form validation</a></li><li><a href=\"/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data\">Sending form data</a></li></ol></details></li><li><details><summary>Advanced web form techniques</summary><ol><li><a href=\"/en-US/docs/Learn/Forms/How_to_build_custom_form_controls\">How to build custom form controls</a></li><li><a href=\"/en-US/docs/Learn/Forms/Sending_forms_through_JavaScript\">Sending forms through JavaScript</a></li><li><a href=\"/en-US/docs/Learn/Forms/Property_compatibility_table_for_form_controls\">CSS property compatibility table for form controls</a></li><li><a href=\"/en-US/docs/Learn/Forms/HTML_forms_in_legacy_browsers\">HTML forms in legacy browsers</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/Accessibility\">Accessibility — Make the web usable by everyone</a></li><li><details><summary>Accessibility guides</summary><ol><li><a href=\"/en-US/docs/Learn/Accessibility\">Accessibility</a></li><li><a href=\"/en-US/docs/Learn/Accessibility/What_is_accessibility\">What is accessibility?</a></li><li><a href=\"/en-US/docs/Learn/Accessibility/HTML\">HTML: A good basis for accessibility</a></li><li><a href=\"/en-US/docs/Learn/Accessibility/CSS_and_JavaScript\">CSS and JavaScript accessibility best practices</a></li><li><a href=\"/en-US/docs/Learn/Accessibility/WAI-ARIA_basics\">WAI-ARIA basics</a></li><li><a href=\"/en-US/docs/Learn/Accessibility/Multimedia\">Accessible multimedia</a></li><li><a href=\"/en-US/docs/Learn/Accessibility/Mobile\">Mobile accessibility</a></li><li><a href=\"/en-US/docs/Learn/Accessibility/Accessibility_troubleshooting\">Assessment: Accessibility troubleshooting</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/Performance\">Performance — Making websites fast and responsive</a></li><li><details><summary>Performance guides</summary><ol><li><a href=\"/en-US/docs/Learn/Performance\">Web performance</a></li><li><a href=\"/en-US/docs/Learn/Performance/why_web_performance\">The \"why\" of web performance</a></li><li><a href=\"/en-US/docs/Learn/Performance/What_is_web_performance\">What is web performance?</a></li><li><a href=\"/en-US/docs/Learn/Performance/Perceived_performance\">Perceived performance</a></li><li><a href=\"/en-US/docs/Learn/Performance/Measuring_performance\">Measuring performance</a></li><li><a href=\"/en-US/docs/Learn/Performance/Multimedia\">Multimedia: Images</a></li><li><a href=\"/en-US/docs/Learn/Performance/video\">Multimedia: video</a></li><li><a href=\"/en-US/docs/Learn/Performance/JavaScript\">JavaScript performance optimization</a></li><li><a href=\"/en-US/docs/Learn/Performance/HTML\">HTML performance optimization</a></li><li><a href=\"/en-US/docs/Learn/Performance/CSS\">CSS performance optimization</a></li><li><a href=\"/en-US/docs/Learn/Performance/business_case_for_performance\">The business case for web performance</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/MathML\">MathML — Writing mathematics with MathML</a></li><li><details><summary>MathML first steps</summary><ol><li><a href=\"/en-US/docs/Learn/MathML/First_steps\">MathML first steps</a></li><li><a href=\"/en-US/docs/Learn/MathML/First_steps/Getting_started\">Getting started with MathML</a></li><li><a href=\"/en-US/docs/Learn/MathML/First_steps/Text_containers\">MathML Text Containers</a></li><li><a href=\"/en-US/docs/Learn/MathML/First_steps/Fractions_and_roots\">MathML fractions and roots</a></li><li><a href=\"/en-US/docs/Learn/MathML/First_steps/Scripts\">MathML scripted elements</a></li><li><a href=\"/en-US/docs/Learn/MathML/First_steps/Tables\">MathML tables</a></li><li><a href=\"/en-US/docs/Learn/MathML/First_steps/Three_famous_mathematical_formulas\">Three famous mathematical formulas</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/../Games\">Games — Developing games for the web</a></li><li><details><summary>Guides and tutorials</summary><ol><li><a href=\"/en-US/docs/Games/Introduction\">Introduction to game development for the Web</a></li><li><a href=\"/en-US/docs/Games/Techniques\">Techniques for game development</a></li><li><a href=\"/en-US/docs/Games/Tutorials\">Tutorials</a></li><li><a href=\"/en-US/docs/Games/Publishing_games\">Publishing games</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/Tools_and_testing\">Tools and testing</a></li><li><details><summary>Client-side web development tools</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools\">Understanding client-side web development tools</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview\">Client-side tooling overview</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line\">Command line crash course</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management\">Package management basics</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Introducing_complete_toolchain\">Introducing a complete toolchain</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Deployment\">Deploying our app</a></li></ol></details></li><li><details><summary>Introduction to client-side frameworks</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction\">Introduction to client-side frameworks</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features\">Framework main features</a></li></ol></details></li><li><details><summary>React</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started\">Getting started with React</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning\">Beginning our React todo list</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components\">Componentizing our React app</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state\">React interactivity: Events and state</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering\">React interactivity: Editing, filtering, conditional rendering</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility\">Accessibility in React</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources\">React resources</a></li></ol></details></li><li><details><summary>Ember</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started\">Getting started with Ember</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization\">Ember app structure and componentization</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state\">Ember interactivity: Events, classes and state</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer\">Ember Interactivity: Footer functionality, conditional rendering</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing\">Routing in Ember</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources\">Ember resources and troubleshooting</a></li></ol></details></li><li><details><summary>Vue</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started\">Getting started with Vue</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component\">Creating our first Vue component</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists\">Rendering a list of Vue components</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models\">Adding a new todo form: Vue events, methods, and models</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling\">Styling Vue components with CSS</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties\">Using Vue computed properties</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering\">Vue conditional rendering: editing existing todos</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management\">Vue refs and lifecycle methods for focus management</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources\">Vue resources</a></li></ol></details></li><li><details><summary>Svelte</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started\">Getting started with Svelte</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning\">Starting our Svelte to-do list app</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props\">Dynamic behavior in Svelte: working with variables and props</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components\">Componentizing our Svelte app</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility\">Advanced Svelte: Reactivity, lifecycle, accessibility</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores\">Working with Svelte stores</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript\">TypeScript support in Svelte</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next\">Deployment and next steps</a></li></ol></details></li><li><details><summary>Angular</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_getting_started\">Getting started with Angular</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_todo_list_beginning\">Beginning our Angular todo list app</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_styling\">Styling our Angular app</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_item_component\">Creating an item component</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_filtering\">Filtering our to-do items</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_building\">Building Angular applications and further resources</a></li></ol></details></li><li><details><summary>Git and GitHub</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/GitHub\">Git and GitHub</a></li></ol></details></li><li><details><summary>Cross browser testing</summary><ol><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing\">Cross browser testing</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction\">Introduction to cross-browser testing</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies\">Strategies for carrying out testing</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS\">Handling common HTML and CSS problems</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript\">Handling common JavaScript problems</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility\">Handling common accessibility problems</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection\">Implementing feature detection</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing\">Introduction to automated testing</a></li><li><a href=\"/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment\">Setting up your own test automation environment</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/Server-side\">Server-side website programming</a></li><li><details open=\"\"><summary>First steps</summary><ol><li><a href=\"/en-US/docs/Learn/Server-side/First_steps\">Server-side website programming first steps</a></li><li><a href=\"/en-US/docs/Learn/Server-side/First_steps/Introduction\">Introduction to the server side</a></li><li><a href=\"/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview\">Client-Server Overview</a></li><li><em><a href=\"/en-US/docs/Learn/Server-side/First_steps/Web_frameworks\" aria-current=\"page\">Server-side web frameworks</a></em></li><li><a href=\"/en-US/docs/Learn/Server-side/First_steps/Website_security\">Website security</a></li></ol></details></li><li><details><summary>Django web framework (Python)</summary><ol><li><a href=\"/en-US/docs/Learn/Server-side/Django\">Django Web Framework (Python)</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Introduction\">Django introduction</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/development_environment\">Setting up a Django development environment</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website\">Django Tutorial: The Local Library website</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/skeleton_website\">Django Tutorial Part 2: Creating a skeleton website</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Models\">Django Tutorial Part 3: Using models</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Admin_site\">Django Tutorial Part 4: Django admin site</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Home_page\">Django Tutorial Part 5: Creating our home page</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Generic_views\">Django Tutorial Part 6: Generic list and detail views</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Sessions\">Django Tutorial Part 7: Sessions framework</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Authentication\">Django Tutorial Part 8: User authentication and permissions</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Forms\">Django Tutorial Part 9: Working with forms</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Testing\">Django Tutorial Part 10: Testing a Django web application</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/Deployment\">Django Tutorial Part 11: Deploying Django to production</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/web_application_security\">Django web application security</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Django/django_assessment_blog\">Assessment: DIY Django mini blog</a></li></ol></details></li><li><details><summary>Express Web Framework (Node.js/JavaScript)</summary><ol><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs\">Express web framework (Node.js/JavaScript)</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction\">Express/Node introduction</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment\">Setting up a Node development environment</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website\">Express Tutorial: The Local Library website</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website\">Express Tutorial Part 2: Creating a skeleton website</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose\">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/routes\">Express Tutorial Part 4: Routes and controllers</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data\">Express Tutorial Part 5: Displaying library data</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/forms\">Express Tutorial Part 6: Working with forms</a></li><li><a href=\"/en-US/docs/Learn/Server-side/Express_Nodejs/deployment\">Express Tutorial Part 7: Deploying to production</a></li></ol></details></li><li class=\"section\"><a href=\"/en-US/docs/Learn/Common_questions\">Further resources</a></li><li><details><summary>Common questions</summary><ol><li><a href=\"/en-US/docs/Learn/Common_questions\">Common questions</a></li><li><a href=\"/en-US/docs/Learn/HTML/Howto\">Use HTML to solve common problems</a></li><li><a href=\"/en-US/docs/Learn/CSS/Howto\">Use CSS to solve common problems</a></li><li><a href=\"/en-US/docs/Learn/JavaScript/Howto\">Solve common problems in your JavaScript code</a></li><li><a href=\"/en-US/docs/Learn/Common_questions/Web_mechanics\">Web mechanics</a></li><li><a href=\"/en-US/docs/Learn/Common_questions/Tools_and_setup\">Tools and setup</a></li><li><a href=\"/en-US/docs/Learn/Common_questions/Design_and_accessibility\">Design and accessibility</a></li></ol></details></li></ol>","sidebarMacro":"LearnSidebar","body":[{"type":"prose","value":{"id":null,"title":null,"isH3":false,"content":"<ul class=\"prev-next\">\n <li><a class=\"button secondary\" href=\"/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview\"><span class=\"button-wrap\"> Previous </span></a></li>\n <li><a class=\"button secondary\" href=\"/en-US/docs/Learn/Server-side/First_steps\"><span class=\"button-wrap\"> Overview: Server-side website programming first steps</span></a></li>\n <li><a class=\"button secondary\" href=\"/en-US/docs/Learn/Server-side/First_steps/Website_security\"><span class=\"button-wrap\"> Next </span></a></li>\n</ul>\n<p>The previous article showed you what the communication between web clients and servers looks like, the nature of HTTP requests and responses, and what a server-side web application needs to do in order to respond to requests from a web browser. With this knowledge under our belt, it's time to explore how web frameworks can simplify these tasks, and give you an idea of how you'd choose a framework for your first server-side web application.</p>\n<figure class=\"table-container\"><table>\n <tbody>\n <tr>\n <th scope=\"row\">Prerequisites:</th>\n <td>\n Basic understanding of how server-side code\n handles and responds to HTTP requests (see <a href=\"/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview\">Client-Server overview</a>).\n </td>\n </tr>\n <tr>\n <th scope=\"row\">Objective:</th>\n <td>\n To understand how web frameworks can simplify development/maintenance of\n server-side code and to get readers thinking about selecting a framework\n for their own development.\n </td>\n </tr>\n </tbody>\n</table></figure>\n<p>The following sections illustrate some points using code fragments taken from real web frameworks. Don't be concerned if it doesn't <strong>all</strong> make sense now; we'll be working you through the code in our framework-specific modules.</p>"}},{"type":"prose","value":{"id":"overview","title":"Overview","isH3":false,"content":"<p>Server-side web frameworks (a.k.a. \"web application frameworks\") are software frameworks that make it easier to write, maintain and scale web applications. They provide tools and libraries that simplify common web development tasks, including routing URLs to appropriate handlers, interacting with databases, supporting sessions and user authorization, formatting output (e.g. HTML, JSON, XML), and improving security against web attacks.</p>\n<p>The next section provides a bit more detail about how web frameworks can ease web application development. We then explain some of the criteria you can use for choosing a web framework, and then list some of your options.</p>"}},{"type":"prose","value":{"id":"what_can_a_web_framework_do_for_you","title":"What can a web framework do for you?","isH3":false,"content":"<p>Web frameworks provide tools and libraries to simplify common web development operations. You don't <em>have</em> to use a server-side web framework, but it is strongly advised — it will make your life a lot easier.</p>\n<p>This section discusses some of the functionality that is often provided by web frameworks (not every framework will necessarily provide all of these features!).</p>"}},{"type":"prose","value":{"id":"work_directly_with_http_requests_and_responses","title":"Work directly with HTTP requests and responses","isH3":true,"content":"<p>As we saw in the last article, web servers and browsers communicate via the HTTP protocol — servers wait for HTTP requests from the browser and then return information in HTTP responses. Web frameworks allow you to write simplified syntax that will generate server-side code to work with these requests and responses. This means that you will have an easier job, interacting with easier, higher-level code rather than lower level networking primitives.</p>\n<p>The example below shows how this works in the Django (Python) web framework. Every \"view\" function (a request handler) receives an <code>HttpRequest</code> object containing request information, and is required to return an <code>HttpResponse</code> object with the formatted output (in this case a string).</p>\n<div class=\"code-example\"><div class=\"example-header\"><span class=\"language-name\">python</span></div><pre class=\"brush: python notranslate\"><code># Django view function\nfrom django.http import HttpResponse\n\ndef index(request):\n # Get an HttpRequest (request)\n # perform operations using information from the request.\n # Return HttpResponse\n return HttpResponse('Output string to return')\n</code></pre></div>"}},{"type":"prose","value":{"id":"route_requests_to_the_appropriate_handler","title":"Route requests to the appropriate handler","isH3":true,"content":"<p>Most sites will provide a number of different resources, accessible through distinct URLs. Handling these all in one function would be hard to maintain, so web frameworks provide simple mechanisms to map URL patterns to specific handler functions. This approach also has benefits in terms of maintenance, because you can change the URL used to deliver a particular feature without having to change the underlying code.</p>\n<p>Different frameworks use different mechanisms for the mapping. For example, the Flask (Python) web framework adds routes to view functions using a decorator.</p>\n<div class=\"code-example\"><div class=\"example-header\"><span class=\"language-name\">python</span></div><pre class=\"brush: python notranslate\"><code>@app.route(\"/\")\ndef hello():\n return \"Hello World!\"\n</code></pre></div>\n<p>While Django expects developers to define a list of URL mappings between a URL pattern and a view function.</p>\n<div class=\"code-example\"><div class=\"example-header\"><span class=\"language-name\">python</span></div><pre class=\"brush: python notranslate\"><code>urlpatterns = [\n url(r'^$', views.index),\n # example: /best/my_team_name/5/\n url(r'^best/(?P<team_name>\\w+?)/(?P<team_number>[0-9]+)/$', views.best),\n]\n</code></pre></div>"}},{"type":"prose","value":{"id":"make_it_easy_to_access_data_in_the_request","title":"Make it easy to access data in the request","isH3":true,"content":"<p>Data can be encoded in an HTTP request in a number of ways. An HTTP <code>GET</code> request to get files or data from the server may encode what data is required in URL parameters or within the URL structure. An HTTP <code>POST</code> request to update a resource on the server will instead include the update information as \"POST data\" within the body of the request. The HTTP request may also include information about the current session or user in a client-side cookie.</p>\n<p>Web frameworks provide programming-language-appropriate mechanisms to access this information. For example, the <code>HttpRequest</code> object that Django passes to every view function contains methods and properties for accessing the target URL, the type of request (e.g. an HTTP <code>GET</code>), <code>GET</code> or <code>POST</code> parameters, cookie and session data, etc. Django can also pass information encoded in the structure of the URL by defining \"capture patterns\" in the URL mapper (see the last code fragment in the section above).</p>"}},{"type":"prose","value":{"id":"abstract_and_simplify_database_access","title":"Abstract and simplify database access","isH3":true,"content":"<p>Websites use databases to store information both to be shared with users, and about users. Web frameworks often provide a database layer that abstracts database read, write, query, and delete operations. This abstraction layer is referred to as an Object-Relational Mapper (ORM).</p>\n<p>Using an ORM has two benefits:</p>\n<ul>\n <li>You can replace the underlying database without necessarily needing to change the code that uses it. This allows developers to optimize for the characteristics of different databases based on their usage.</li>\n <li>Basic validation of data can be implemented within the framework. This makes it easier and safer to check that data is stored in the correct type of database field, has the correct format (e.g. an email address), and isn't malicious in any way (hackers can use certain patterns of code to do bad things such as deleting database records).</li>\n</ul>\n<p>For example, the Django web framework provides an ORM, and refers to the object used to define the structure of a record as the <em>model</em>. The model specifies the field <em>types</em> to be stored, which may provide field-level validation on what information can be stored (e.g. an email field would only allow valid email addresses). The field definitions may also specify their maximum size, default values, selection list options, help text for documentation, label text for forms etc. The model doesn't state any information about the underlying database as that is a configuration setting that may be changed separately of our code.</p>\n<p>The first code snippet below shows a very simple Django model for a <code>Team</code> object. This stores the team name and team level as character fields and specifies a maximum number of characters to be stored for each record. The <code>team_level</code> is a choice field, so we also provide a mapping between choices to be displayed and data to be stored, along with a default value.</p>\n<div class=\"code-example\"><div class=\"example-header\"><span class=\"language-name\">python</span></div><pre class=\"brush: python notranslate\"><code>#best/models.py\n\nfrom django.db import models\n\nclass Team(models.Model):\n team_name = models.CharField(max_length=40)\n\n TEAM_LEVELS = (\n ('U09', 'Under 09s'),\n ('U10', 'Under 10s'),\n ('U11', 'Under 11s'),\n # List our other teams\n )\n team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')\n</code></pre></div>\n<p>The Django model provides a simple query API for searching the database. This can match against a number of fields at a time using different criteria (e.g. exact, case-insensitive, greater than, etc.), and can support complex statements (for example, you can specify a search on U11 teams that have a team name that starts with \"Fr\" or ends with \"al\").</p>\n<p>The second code snippet shows a view function (resource handler) for displaying all of our U09 teams. In this case we specify that we want to filter for all records where the <code>team_level</code> field has exactly the text 'U09' (note below how this criteria is passed to the <code>filter()</code> function as an argument with field name and match type separated by double underscores: <strong>team_level__exact</strong>).</p>\n<div class=\"code-example\"><div class=\"example-header\"><span class=\"language-name\">python</span></div><pre class=\"brush: python notranslate\"><code>#best/views.py\n\nfrom django.shortcuts import render\nfrom .models import Team\n\ndef youngest(request):\n list_teams = Team.objects.filter(team_level__exact=\"U09\")\n context = {'youngest_teams': list_teams}\n return render(request, 'best/index.html', context)\n</code></pre></div>"}},{"type":"prose","value":{"id":"rendering_data","title":"Rendering data","isH3":true,"content":"<p>Web frameworks often provide templating systems. These allow you to specify the structure of an output document, using placeholders for data that will be added when a page is generated. Templates are often used to create HTML, but can also create other types of documents.</p>\n<p>Web frameworks often provide a mechanism to make it easy to generate other formats from stored data, including <a href=\"/en-US/docs/Glossary/JSON\">JSON</a> and <a href=\"/en-US/docs/Glossary/XML\">XML</a>.</p>\n<p>For example, the Django template system allows you to specify variables using a \"double-handlebars\" syntax (e.g. <code>{{ variable_name }}</code>), which will be replaced by values passed in from the view function when a page is rendered. The template system also provides support for expressions (with syntax: <code>{% expression %}</code>), which allow templates to perform simple operations like iterating list values passed into the template.</p>\n<div class=\"notecard note\">\n <p><strong>Note:</strong> Many other templating systems use a similar syntax, e.g.: Jinja2 (Python), handlebars (JavaScript), moustache (JavaScript), etc.</p>\n</div>\n<p>The code snippet below shows how this works. Continuing the \"youngest team\" example from the previous section, the HTML template is passed a list variable called <code>youngest_teams</code> by the view. Inside the HTML skeleton we have an expression that first checks if the <code>youngest_teams</code> variable exists, and then iterates it in a <code>for</code> loop. On each iteration the template displays the team's <code>team_name</code> value in a list item.</p>\n<div class=\"code-example\"><div class=\"example-header\"><span class=\"language-name\">django</span></div><pre class=\"brush: django notranslate\"><code>#best/templates/best/index.html\n\n<!doctype html>\n<html lang=\"en\">\n <body>\n {% if youngest_teams %}\n <ul>\n {% for team in youngest_teams %}\n <li>{{ team.team_name }}</li>\n {% endfor %}\n </ul>\n {% else %}\n <p>No teams are available.</p>\n {% endif %}\n </body>\n</html>\n</code></pre></div>"}},{"type":"prose","value":{"id":"how_to_select_a_web_framework","title":"How to select a web framework","isH3":false,"content":"<p>Numerous web frameworks exist for almost every programming language you might want to use (we list a few of the more popular frameworks in the following section). With so many choices, it can become difficult to work out what framework provides the best starting point for your new web application.</p>\n<p>Some of the factors that may affect your decision are:</p>\n<ul>\n <li>\n <p><strong>Effort to learn:</strong> The effort to learn a web framework depends on how familiar you are with the underlying programming language, the consistency of its API, the quality of its documentation, and the size and activity of its community. If you're starting from absolutely no programming experience then consider Django (it is one of the easiest to learn based on the above criteria). If you are part of a development team that already has significant experience with a particular web framework or programming language, then it makes sense to stick with that.</p>\n </li>\n <li>\n <p><strong>Productivity:</strong> Productivity is a measure of how quickly you can create new features once you are familiar with the framework, and includes both the effort to write and maintain code (since you can't write new features while old ones are broken). Many of the factors affecting productivity are similar to those for \"Effort to learn\" — e.g. documentation, community, programming experience, etc. — other factors include:</p>\n <ul>\n <li><em>Framework purpose/origin</em>: Some web frameworks were initially created to solve certain types of problems, and remain <em>better</em> at creating web apps with similar constraints. For example, Django was created to support development of a newspaper website, so it's good for blogs and other sites that involve publishing things. By contrast, Flask is a much lighter-weight framework and is great for creating web apps running on embedded devices.</li>\n <li><em>Opinionated vs. unopinionated</em>: An opinionated framework is one in which there are recommended \"best\" ways to solve a particular problem. Opinionated frameworks tend to be more productive when you're trying to solve common problems, because they lead you in the right direction, however they are sometimes less flexible.</li>\n <li><em>Batteries included vs. get it yourself</em>: Some web frameworks include tools/libraries that address every problem their developers can think \"by default\", while more lightweight frameworks expect web developers to pick and choose solution to problems from separate libraries (Django is an example of the former, while Flask is an example of a very light-weight framework). Frameworks that include everything are often easier to get started with because you already have everything you need, and the chances are that it is well integrated and well documented. However if a smaller framework has everything you (will ever) need then it can run in more constrained environments and will have a smaller and easier subset of things to learn.</li>\n <li><em>Whether or not the framework encourages good development practices</em>: For example, a framework that encourages a <a href=\"/en-US/docs/Glossary/MVC\">Model-View-Controller</a> architecture to separate code into logical functions will result in more maintainable code than one that has no expectations on developers. Similarly, framework design can have a large impact on how easy it is to test and re-use code.</li>\n </ul>\n </li>\n <li>\n <p><strong>Performance of the framework/programming language:</strong> Usually \"speed\" is not the biggest factor in selection because even relatively slow runtimes like Python are more than \"good enough\" for mid-sized sites running on moderate hardware. The perceived speed benefits of another language, e.g. C++ or JavaScript, may well be offset by the costs of learning and maintenance.</p>\n </li>\n <li>\n <p><strong>Caching support:</strong> As your website becomes more successful then you may find that it can no longer cope with the number of requests it is receiving as users access it. At this point you may consider adding support for caching. Caching is an optimization where you store all or part of a web response so that it does not have to be recalculated on subsequent requests. Returning a cached response is much faster than calculating one in the first place. Caching can be implemented in your code or in the server (see <a href=\"https://en.wikipedia.org/wiki/Reverse_proxy\" class=\"external\" target=\"_blank\">reverse proxy</a>). Web frameworks will have different levels of support for defining what content can be cached.</p>\n </li>\n <li>\n <p><strong>Scalability:</strong> Once your website is fantastically successful you will exhaust the benefits of caching and even reach the limits of <em>vertical scaling</em> (running your web application on more powerful hardware). At this point you may need to <em>scale horizontally</em> (share the load by distributing your site across a number of web servers and databases) or scale \"geographically\" because some of your customers are based a long way away from your server. The web framework you choose can make a big difference on how easy it is to scale your site.</p>\n </li>\n <li>\n <p><strong>Web security:</strong> Some web frameworks provide better support for handling common web attacks. Django for example sanitizes all user input from HTML templates so that user-entered JavaScript cannot be run. Other frameworks provide similar protection, but it is not always enabled by default.</p>\n </li>\n</ul>\n<p>There are many other possible factors, including licensing, whether or not the framework is under active development, etc.</p>\n<p>If you're an absolute beginner at programming then you'll probably choose your framework based on \"ease of learning\". In addition to \"ease of use\" of the language itself, high quality documentation/tutorials and an active community helping new users are your most valuable resources. We've chosen <a href=\"https://www.djangoproject.com/\" class=\"external\" target=\"_blank\">Django</a> (Python) and <a href=\"https://expressjs.com/\" class=\"external\" target=\"_blank\">Express</a> (Node/JavaScript) to write our examples later on in the course, mainly because they are easy to learn and have good support.</p>\n<div class=\"notecard note\">\n <p><strong>Note:</strong> Let's go to the main websites for <a href=\"https://www.djangoproject.com/\" class=\"external\" target=\"_blank\">Django</a> (Python) and <a href=\"https://expressjs.com/\" class=\"external\" target=\"_blank\">Express</a> (Node/JavaScript) and check out their documentation and community.</p>\n <ol>\n <li>\n <p>Navigate to the main sites (linked above)</p>\n <ul>\n <li>Click on the Documentation menu links (named things like \"Documentation, Guide, API Reference, Getting Started\", etc.).</li>\n <li>Can you see topics showing how to set up URL routing, templates, and databases/models?</li>\n <li>Are the documents clear?</li>\n </ul>\n </li>\n <li>\n <p>Navigate to mailing lists for each site (accessible from Community links).</p>\n <ul>\n <li>How many questions have been posted in the last few days</li>\n <li>How many have responses?</li>\n <li>Do they have an active community?</li>\n </ul>\n </li>\n </ol>\n</div>"}},{"type":"prose","value":{"id":"a_few_good_web_frameworks","title":"A few good web frameworks?","isH3":false,"content":"<p>Let's now move on, and discuss a few specific server-side web frameworks.</p>\n<p>The server-side frameworks below represent <em>a few</em> of the most popular available at the time of writing. All of them have everything you need to be productive — they are open source, are under active development, have enthusiastic communities creating documentation and helping users on discussion boards, and are used in large numbers of high-profile websites. There are many other great server-side frameworks that you can discover using a basic internet search.</p>\n<div class=\"notecard note\">\n <p><strong>Note:</strong> Descriptions come (partially) from the framework websites!</p>\n</div>"}},{"type":"prose","value":{"id":"django_python","title":"Django (Python)","isH3":true,"content":"<p><a href=\"https://www.djangoproject.com/\" class=\"external\" target=\"_blank\">Django</a> is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel. It's free and open source.</p>\n<p>Django follows the \"Batteries included\" philosophy and provides almost everything most developers might want to do \"out of the box\". Because everything is included, it all works together, follows consistent design principles, and has extensive and up-to-date documentation. It is also fast, secure, and very scalable. Being based on Python, Django code is easy to read and to maintain.</p>\n<p>Popular sites using Django (from Django home page) include: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest, Open Stack.</p>"}},{"type":"prose","value":{"id":"flask_python","title":"Flask (Python)","isH3":true,"content":"<p><a href=\"https://flask.palletsprojects.com/\" class=\"external\" target=\"_blank\">Flask</a> is a microframework for Python.</p>\n<p>While minimalist, Flask can create serious websites out of the box. It contains a development server and debugger, and includes support for <a href=\"https://github.com/pallets/jinja\" class=\"external\" target=\"_blank\">Jinja2</a> templating, secure cookies, <a href=\"https://en.wikipedia.org/wiki/Unit_testing\" class=\"external\" target=\"_blank\">unit testing</a>, and <a href=\"https://restapitutorial.com/\" class=\"external\" target=\"_blank\">RESTful</a> request dispatching. It has good documentation and an active community.</p>\n<p>Flask has become extremely popular, particularly for developers who need to provide web services on small, resource-constrained systems (e.g. running a web server on a <a href=\"https://www.raspberrypi.org/\" class=\"external\" target=\"_blank\">Raspberry Pi</a>, <a href=\"https://www.techuseful.com/drone-definitions-learning-the-drone-lingo/\" class=\"external\" target=\"_blank\">Drone controllers</a>, etc.)</p>"}},{"type":"prose","value":{"id":"express_node.jsjavascript","title":"Express (Node.js/JavaScript)","isH3":true,"content":"<p><a href=\"https://expressjs.com/\" class=\"external\" target=\"_blank\">Express</a> is a fast, unopinionated, flexible and minimalist web framework for <a href=\"https://nodejs.org/en/\" class=\"external\" target=\"_blank\">Node.js</a> (node is a browserless environment for running JavaScript). It provides a robust set of features for web and mobile applications and delivers useful HTTP utility methods and <a href=\"/en-US/docs/Glossary/Middleware\">middleware</a>.</p>\n<p>Express is extremely popular, partially because it eases the migration of client-side JavaScript web programmers into server-side development, and partially because it is resource-efficient (the underlying node environment uses lightweight multitasking within a thread rather than spawning separate processes for every new web request).</p>\n<p>Because Express is a minimalist web framework it does not incorporate every component that you might want to use (for example, database access and support for users and sessions are provided through independent libraries). There are many excellent independent components, but sometimes it can be hard to work out which is the best for a particular purpose!</p>\n<p>Many popular server-side and full stack frameworks (comprising both server and client-side frameworks) are based on Express, including <a href=\"https://feathersjs.com/\" class=\"external\" target=\"_blank\">Feathers</a>, <a href=\"https://itemsapi.com/\" class=\"external\" target=\"_blank\">ItemsAPI</a>, <a href=\"https://keystonejs.com/\" class=\"external\" target=\"_blank\">KeystoneJS</a>, <a href=\"https://krakenjs.com/\" class=\"external\" target=\"_blank\">Kraken</a>, <a href=\"https://loopback.io/\" class=\"external\" target=\"_blank\">LoopBack</a>, <a href=\"https://github.com/linnovate/mean\" class=\"external\" target=\"_blank\">MEAN</a>, and <a href=\"https://sailsjs.com/\" class=\"external\" target=\"_blank\">Sails</a>.</p>\n<p>A lot of high profile companies use Express, including: Uber, Accenture, IBM, etc.</p>"}},{"type":"prose","value":{"id":"deno_javascript","title":"Deno (JavaScript)","isH3":true,"content":"<p><a href=\"https://deno.com/\" class=\"external\" target=\"_blank\">Deno</a> is a simple, modern, and secure <a href=\"/en-US/docs/Web/JavaScript\">JavaScript</a>/TypeScript runtime and framework built on top of Chrome V8 and <a href=\"https://www.rust-lang.org/\" class=\"external\" target=\"_blank\">Rust</a>.</p>\n<p>Deno is powered by <a href=\"https://tokio.rs/\" class=\"external\" target=\"_blank\">Tokio</a> — a Rust-based asynchronous runtime which lets it serve web pages faster. It also has internal support for <a href=\"/en-US/docs/WebAssembly\">WebAssembly</a>, which enables the compilation of binary code for use on the client-side. Deno aims to fill in some of the loop-holes in <a href=\"/en-US/docs/Learn/Server-side/Node_server_without_framework\">Node.js</a> by providing a mechanism that naturally maintains better security.</p>\n<p>Deno's features include:</p>\n<ul>\n <li>Security by default. <a href=\"https://docs.deno.com/runtime/fundamentals/security/\" class=\"external\" target=\"_blank\">Deno modules restrict permissions</a> to <strong>file</strong>, <strong>network</strong>, or <strong>environment</strong> access unless explicitly allowed.</li>\n <li>TypeScript support <strong>out-of-the-box</strong>.</li>\n <li>First-class await mechanism.</li>\n <li>Built-in testing facility and code formatter (<code>deno fmt</code>)</li>\n <li>(JavaScript) Browser compatibility: Deno programs that are written completely in JavaScript excluding the <code>Deno</code> namespace (or feature test for it), should work directly in any modern browser.</li>\n <li>Script bundling into a single JavaScript file.</li>\n</ul>\n<p>Deno provides an easy yet powerful way to use JavaScript for both client- and server-side programming.</p>"}},{"type":"prose","value":{"id":"ruby_on_rails_ruby","title":"Ruby on Rails (Ruby)","isH3":true,"content":"<p><a href=\"https://rubyonrails.org/\" class=\"external\" target=\"_blank\">Rails</a> (usually referred to as \"Ruby on Rails\") is a web framework written for the Ruby programming language.</p>\n<p>Rails follows a very similar design philosophy to Django. Like Django it provides standard mechanisms for routing URLs, accessing data from a database, generating HTML from templates and formatting data as <a href=\"/en-US/docs/Glossary/JSON\">JSON</a> or <a href=\"/en-US/docs/Glossary/XML\">XML</a>. It similarly encourages the use of design patterns like DRY (\"don't repeat yourself\" — write code only once if at all possible), MVC (model-view-controller) and a number of others.</p>\n<p>There are of course many differences due to specific design decisions and the nature of the languages.</p>\n<p>Rails has been used for high profile sites, including: <a href=\"https://basecamp.com/\" class=\"external\" target=\"_blank\">Basecamp</a>, <a href=\"https://github.com/\" class=\"external\" target=\"_blank\">GitHub</a>, <a href=\"https://www.shopify.com/\" class=\"external\" target=\"_blank\">Shopify</a>, <a href=\"https://www.airbnb.com/\" class=\"external\" target=\"_blank\">Airbnb</a>, <a href=\"https://www.twitch.tv/\" class=\"external\" target=\"_blank\">Twitch</a>, <a href=\"https://soundcloud.com/\" class=\"external\" target=\"_blank\">SoundCloud</a>, <a href=\"https://www.hulu.com/welcome\" class=\"external\" target=\"_blank\">Hulu</a>, <a href=\"https://www.zendesk.com/\" class=\"external\" target=\"_blank\">Zendesk</a>, <a href=\"https://squareup.com/us/en\" class=\"external\" target=\"_blank\">Square</a>, <a href=\"https://highrisehq.com/\" class=\"external\" target=\"_blank\">Highrise</a>.</p>"}},{"type":"prose","value":{"id":"laravel_php","title":"Laravel (PHP)","isH3":true,"content":"<p><a href=\"https://laravel.com/\" class=\"external\" target=\"_blank\">Laravel</a> is a web application framework with expressive, elegant syntax. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as:</p>\n<ul>\n <li><a href=\"https://laravel.com/docs/routing\" class=\"external\" target=\"_blank\">Simple, fast routing engine</a>.</li>\n <li><a href=\"https://laravel.com/docs/container\" class=\"external\" target=\"_blank\">Powerful dependency injection container</a>.</li>\n <li>Multiple back-ends for <a href=\"https://laravel.com/docs/session\" class=\"external\" target=\"_blank\">session</a> and <a href=\"https://laravel.com/docs/cache\" class=\"external\" target=\"_blank\">cache</a> storage.</li>\n <li>Expressive, intuitive <a href=\"https://laravel.com/docs/eloquent\" class=\"external\" target=\"_blank\">database ORM</a>.</li>\n <li>Database agnostic <a href=\"https://laravel.com/docs/migrations\" class=\"external\" target=\"_blank\">schema migrations</a>.</li>\n <li><a href=\"https://laravel.com/docs/queues\" class=\"external\" target=\"_blank\">Robust background job processing</a>.</li>\n <li><a href=\"https://laravel.com/docs/broadcasting\" class=\"external\" target=\"_blank\">Real-time event broadcasting</a>.</li>\n</ul>\n<p>Laravel is accessible, yet powerful, providing tools needed for large, robust applications.</p>"}},{"type":"prose","value":{"id":"asp.net","title":"ASP.NET","isH3":true,"content":"<p><a href=\"https://dotnet.microsoft.com/en-us/apps/aspnet\" class=\"external\" target=\"_blank\">ASP.NET</a> is an open source web framework developed by Microsoft for building modern web applications and services. With ASP.NET you can quickly create websites based on HTML, CSS, and JavaScript, scale them for use by millions of users and easily add more complex capabilities like Web APIs, forms over data, or real time communications.</p>\n<p>One of the differentiators for ASP.NET is that it is built on the <a href=\"https://en.wikipedia.org/wiki/Common_Language_Runtime\" class=\"external\" target=\"_blank\">Common Language Runtime</a> (CLR), allowing programmers to write ASP.NET code using any supported .NET language (C#, Visual Basic, etc.). Like many Microsoft products it benefits from excellent tools (often free), an active developer community, and well-written documentation.</p>\n<p>ASP.NET is used by Microsoft, Xbox.com, Stack Overflow, and many others.</p>"}},{"type":"prose","value":{"id":"mojolicious_perl","title":"Mojolicious (Perl)","isH3":true,"content":"<p><a href=\"https://mojolicious.org/\" class=\"external\" target=\"_blank\">Mojolicious</a> is a next-generation web framework for the Perl programming language.</p>\n<p>Back in the early days of the web, many people learned Perl because of a wonderful Perl library called <a href=\"https://metacpan.org/pod/CGI\" class=\"external\" target=\"_blank\">CGI</a>. It was simple enough to get started without knowing much about the language and powerful enough to keep you going. Mojolicious implements this idea using bleeding edge technologies.</p>\n<p>Some of the features provided by Mojolicious are:</p>\n<ul>\n <li>A real-time web framework, to easily grow single-file prototypes into well-structured MVC web applications.</li>\n <li>RESTful routes, plugins, commands, Perl-ish templates, content negotiation, session management, form validation, testing framework, static file server, CGI/<a href=\"https://plackperl.org/\" class=\"external\" target=\"_blank\">PSGI</a> detection, and first-class Unicode support.</li>\n <li>A full-stack HTTP and WebSocket client/server implementation with IPv6, TLS, SNI, IDNA, HTTP/SOCKS5 proxy, UNIX domain socket, Comet (long polling), keep-alive, connection pooling, timeout, cookie, multipart, and gzip compression support.</li>\n <li>JSON and HTML/XML parsers and generators with CSS selector support.</li>\n <li>Very clean, portable and object-oriented pure-Perl API with no hidden magic.</li>\n <li>Fresh code based upon years of experience, free and open-source.</li>\n</ul>"}},{"type":"prose","value":{"id":"spring_boot_java","title":"Spring Boot (Java)","isH3":true,"content":"<p><a href=\"https://spring.io/projects/spring-boot/\" class=\"external\" target=\"_blank\">Spring Boot</a> is one of a number of projects provided by <a href=\"https://spring.io/\" class=\"external\" target=\"_blank\">Spring</a>. It is a good starting point for doing server-side web development using <a href=\"https://www.java.com/\" class=\"external\" target=\"_blank\">Java</a>.</p>\n<p>Although definitely not the only framework based on <a href=\"https://www.java.com/\" class=\"external\" target=\"_blank\">Java</a> it is easy to use to create stand-alone, production-grade Spring-based Applications that you can \"just run\". It is an opinionated view of the Spring platform and third-party libraries but allows to start with minimum fuss and configuration.</p>\n<p>It can be used for small problems but its strength is building larger scale applications that use a cloud approach. Usually multiple applications run in parallel talking to each other, with some providing user interaction and others doing back end work (e.g. accessing databases or other services). Load balancers help to ensure redundancy and reliability or allow geolocated handling of user requests to ensure responsiveness.</p>"}},{"type":"prose","value":{"id":"summary","title":"Summary","isH3":false,"content":"<p>This article has shown that web frameworks can make it easier to develop and maintain server-side code. It has also provided a high level overview of a few popular frameworks, and discussed criteria for choosing a web application framework. You should now have at least an idea of how to choose a web framework for your own server-side development. If not, then don't worry — later on in the course we'll give you detailed tutorials on Django and Express to give you some experience of actually working with a web framework.</p>\n<p>For the next article in this module we'll change direction slightly and consider web security.</p><ul class=\"prev-next\">\n <li><a class=\"button secondary\" href=\"/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview\"><span class=\"button-wrap\"> Previous </span></a></li>\n <li><a class=\"button secondary\" href=\"/en-US/docs/Learn/Server-side/First_steps\"><span class=\"button-wrap\"> Overview: Server-side website programming first steps</span></a></li>\n <li><a class=\"button secondary\" href=\"/en-US/docs/Learn/Server-side/First_steps/Website_security\"><span class=\"button-wrap\"> Next </span></a></li>\n</ul>"}}],"toc":[{"text":"Overview","id":"overview"},{"text":"What can a web framework do for you?","id":"what_can_a_web_framework_do_for_you"},{"text":"How to select a web framework","id":"how_to_select_a_web_framework"},{"text":"A few good web frameworks?","id":"a_few_good_web_frameworks"},{"text":"Summary","id":"summary"}],"summary":"This article has shown that web frameworks can make it easier to develop and maintain server-side code. It has also provided a high level overview of a few popular frameworks, and discussed criteria for choosing a web application framework. You should now have at least an idea of how to choose a web framework for your own server-side development. If not, then don't worry — later on in the course we'll give you detailed tutorials on Django and Express to give you some experience of actually working with a web framework.","popularity":0.0059,"modified":"2024-10-31T19:44:02.000Z","other_translations":[{"locale":"de","title":"Serverseitige Web-Frameworks","native":"Deutsch"},{"locale":"es","title":"Frameworks Web de lado servidor","native":"Español"},{"locale":"fr","title":"Les frameworks web côté serveur","native":"Français"},{"locale":"ja","title":"サーバーサイドウェブフレームワーク","native":"日本語"},{"locale":"ko","title":"Server-side web frameworks","native":"한국어"},{"locale":"ru","title":"Выполняемые на сервере веб-фреймворки","native":"Русский"},{"locale":"zh-CN","title":"服务端 web 框架","native":"中文 (简体)"}],"pageType":"learn-module-chapter","source":{"folder":"en-us/learn/server-side/first_steps/web_frameworks","github_url":"https://github.com/mdn/content/blob/main/files/en-us/learn/server-side/first_steps/web_frameworks/index.md","last_commit_url":"https://github.com/mdn/content/commit/41a27d6c0f8e44f1b9a3dabddd9315655b367b77","filename":"index.md"},"short_title":"Server-side web frameworks","parents":[{"uri":"/en-US/docs/Learn","title":"Guides"},{"uri":"/en-US/docs/Learn/Server-side","title":"Server-side website programming"},{"uri":"/en-US/docs/Learn/Server-side/First_steps","title":"Server-side website programming first steps"},{"uri":"/en-US/docs/Learn/Server-side/First_steps/Web_frameworks","title":"Server-side web frameworks"}],"pageTitle":"Server-side web frameworks - Learn web development | MDN","noIndexing":false}}</script></body></html>