This is a simple exercise where I try to build a website (SPA) without any third party dependency or build tool but assuming we were in a world where all browsers have implemented most of the modern proposed Javascript APIs. basic This is what we’ll be building: ( ) demo here Podcaster home page A simple website to look for music podcasts, list their episodes and listen to them. Podcast detail page Episode detail page The main idea is to take a component based approach, so, with that in mind, this is the structure I’ll be using for the code: < > index.html src root + + styles js (here is the code to access podcasts services) (here are the views and partials for the UI) (here is the routing configuration) (support code) * api * components * config * plugins . You can get the final code here The first goodie I’ll be using is in modern browsers (Chrome and Safari). Javascript Modules loading support So, the HTML file would look like this: The important part here is the attribute for the tag.Using the “ ” value you’re telling the browser to use syntax with its APIs. type script module ES2015 javascript modules import/export In the markup, we only set a root entry point where we will our application from the main file. mount Application main file That main file, inserts the application layout (a header with a spinner we’ll use for loading state) and delegates main content rendering to the application router: We just create a new element with the layout and setup the client-side router with the routing configuration, the root element where it should render the main content (based on the URL) and a listener so we can react to loading events (transition across pages when data is not cached). html Router So, client-side routing. Many would automatically look for a third party library because it seems that this is a complex area, but the truth is, if you just need to handle simple navigations, building a router from the scratch is not that difficult. It’s just sync your URL with a component.Regarding to data needed by the rendering component, you can setup the component to load it or you can have the router load it and just pass it to the component. I prefer the second way because I don’t want the new page to begin rendering until I have its data and I also don’t want to handle a state for every page (if you create helper component for this, I think its better just to use the ). loading router Here is the application router: It is a simple one, but it’s enough to begin with.I used this approach in some other projects with a slightly more complex router and I usually create another file for proper handling, and to export some and helper functions. popstate navTo redirectTo So this is what we do: Listen to click events on links in the document Listen to external changes in the URL (example: and buttons from the browser) back forward Fire a first change URL handling when the page loads And when we need to load a new page: Based on the URL we want to navigate to, find the right router configuration Once we have that one, we extract the parameters the data loader might need from the URL Call the loader to fetch required data Update router internal state: new view component and new data Re-render the router main element with the new state by instantiating a new component with the new data and call its function, which returns an . render HTMLElement Restore scroll position There’s also the execution of the callback to show the app loading indicator. Home page Ok, so next thing we need to learn about are the (home, podcast-detail and episode-detail).We’ve just seen that might have a which accepts initial data and a function which must return an with the expected content. pages pages constructor render HTMLElement As all of the will have some common behavior, and we will need several instances of them, we’ll be creating a base class for them which every page will inherit from. pages Our pages will have a touch from and another one from .Let’s begin to take a look at the view. Backbone React HomePage In the of the page we receive the data from the and call parent to store instance state. We will be using that state to re/render the view. constructor router We also have a which returns a map of the DOM events the page must handle. The syntax is inspired by The key for every entry has to parts: the first one is the name of the DOM event we want to listen to and the second part, the for “ the second part is the function we want to associate with the event.Actually, the event listeners are not bound to the elements represented by the selector, they are all bound to the root element for a view instance and there’s a delegation management in the . getter Backbone . selector the element we want to have the listener attached to”; BasePage The function used in the render process is the one, which must return a string representing the HTML to visualize the page with its provided state.In the we saw that we were generating the contents for the page calling a function which returns an HTMLElement. That function is implemented in the class (we’re about to get there). html router render BasePage The last important thing to note is the static function, which is used by the router to know how to load (asynchronously) the data this view requires. dataLoader Base page class So far so good. Let’s take a look at the base class for every application page: In the constructor we store the data received from the page class, create the root HTMLElement for this view and register the possible DOM event handlers the subclass might define. Then, we only have a function to update instance state (which re-renders the page instance) and the render function for setting HTML string produced by the subclass in the root instance HTMLElement. Partials If you get back to the render code, you will notice that every podcast info is rendered using the partial. HomePage PodcastSummary This kind of component is a simpler one because it does not need to handle navigation and don’t need dynamic state.These ones are like in . They just receive the data to render and return the corresponding HTML string. stateless functional components React The rest of the code The code for the other pages are quite similar of what you’ve just seen in the class.There are some other relevant files: HomePage /src/api/ This file holds the AJAX calls to the iTunes podcast services as well as the requests to fetch the podcast RSS detail file. podcaster.js /src/plugins/ This file is a proxy for the local-storage API that allows to store values with a Time To Live meta-info. local-cache.js /src/plugins/ This file is a thin wrapper over the fetch API to simplify its use. ajax.js You can browse/download the to get their details. finished code for this pet project here Conclusion As you can see, with the latest browsers, you can implement a solution with no third party dependencies in a quite easy way. basic I’m sure that, a year or two ahead, when all the browsers have this APIs implemented, there will be newer outstanding ones that will be only available in one or two of them, so we will still waiting for all the browsers to implement them, just as we are now. But, you know? That’s what make our lives entertaining. If you got this far, I want to THANK you for giving me some of your time and I hope you found something useful in this article. : I’ve written a follow-up article to show how easy can be to add to this basic application.Check it out! Extra Bonus code splitting JS: Let’s try the future today (extra bonus)