The Modern .NET Show

Episode 114 - Statiq with Dave Glick

Embedded Player

Episode 114 - Statiq with Dave Glick
The .NET Core Podcast

Episode 114 - Statiq with Dave Glick

Supporting The Show

If this episode was interesting or useful to you, please consider supporting the show with one of the above options.

Episode Transcription

Hello everyone and welcome to THE .NET Core Podcast. An award-winning podcast where we reach into the core of the .NET technology stack and, with the help of the .NET community, present you with the information that you need in order to grok the many moving parts of one of the biggest cross-platform, multi-application frameworks on the planet.

I am your host, Jamie “GaProgMan” Taylor. In this episode, I talked with Dave Glick about Statiq which is a static site generator - although calling it static site generator, as we’ll see, is quite reductive. We also talk about the JAM Stack, static sites, and how most websites don’t actually need something like ASP .NET Core or WordPress generating pages at request time. We also talk about a very small selection of some of the things that you can use Statiq to generate - why not check it out today?

Along the way, Dave dispels some of the common misconceptions of statically generated vs completely dynamically generated websites (i.e. pages generated ahead of time vs pages generated at request time), and I talk about how the website for the show is generated ahead of time, and some of the benefits that the community of listeners get from that. This is a conversation that both Dave and I could have kept going with for hours, but we’ve agreed to come back to it another day in order to explore further.

So let’s sit back, open up a terminal, type in dotnet new podcast and let the show begin.

Jamie

Thank you, Dave, for spending some time with me today with the listeners as well, I really, really appreciate it. I think I think we’re going to be talking about something that a lot of .NET devs don’t really think about, especially in the web space. You know, there’s there’s ASP .NET servers that serve your website and your web API’s and stuff. And a lot of people are used to that sort of, “there is a server that I put a request in it builds a page and brings it back.” And we’re technically not going to talk about that. So that’s going to be an interesting diversion for people, I think. But before we do any of that, why don’t you tell the folks a little bit about yourself? And like I said, welcome to the show.

Dave

Yeah, sure. Thanks for having me, Jamie. And good morning, evening, afternoon, wherever you happen to be listening. So my name is Dave Glick, I have been developing on .NET for well over a decade at this point, way back, pre .NET 2.0, which is kind of when things got fun. I do a lot of open source development, have several open source projects, I’m active with the Cake Build team. And just generally like to participate in the .NET open source community. And kind of as an aside, I’d encourage anyone listening out there who’s interested in open source to hit me up or, you know, look up some of the other active .NET open source folks, and we can help you get started. But today, that’s not what we’re talking about directly. We are talking about some open source projects, however. So that’s a little bit about me in general.

Jamie

Thanks for that. Thanks for that. I always, I always find it’s really useful for the listeners to sort of level set and go, “well, who is this person?” Right. Because the last thing you want is someone who’s an expert, something coming and saying, " not gonna tell you anything about me. Just going to tell you about the thing that I’m an expert in." And that’s like, that’s that’s great. But obviously, there’s obviously the the person-ability over right.

Dave

Oh, sure. Yeah, yeah. So I will I will tell you, I consider myself an expert at nothing, always learning. We are all sort of experts-in-waiting at just about everything, I think.

Jamie

Yep. Yep. I agree with you there. I’m, I’m the furthest from an expert than anyone could be. I’m definitely a wally is how we would say it in the UK parlance. So I’m not sure whether Wally has the same feeling over in the States, but

Dave

it does not. I’ve never even heard that term. I like it. I’m gonna start using it.

Jamie

Fair enough. I do know that the when the Where’s Wally -or rather the Where’s Waldo books - were brought over to the UK, they renamed the character Wally. I don’t know whether it had anything to do with…

Dave

Oh, that’s interesting. That’s a fascinating little bit of history there. Yeah.

Jamie

Yeah, yes. It’s “Where’s Waldo” in the States, and “Where’s Wally” over here in the UK, which I’ve never really understood. But I’m not in the business of localization. So they know what they were doing. And that’s perfectly fine for me.

But yeah, so yeah, I reached out to you because there’s this wonderful open source project that you’ve been working on. And just saying “open source project” is doing it a disservice, because there’s a whole bunch of stuff that he does, I know of it as a static site generator. And this is this is your, your, your project Statiq, right. And I… for the listeners, you’ve all been browsing a static website, a statically generated website, if you’ve gone to the website for the for the podast, because it’s statically generated. That doesn’t mean that it doesn’t change, it just means that my definition of it is that the HTML is generated ahead of time. And so you don’t have a server sitting there receiving a request, generating a page, building that on the server whilst we’re waiting, and then sending that back over the wire. And that was purely from a - I hate to say, but a security standpoint, that’s why I chose a statically generated website. Because there’s no server you can’t… or there is a server but there’s no there’s no like server infrastructure.

Dave

Yeah. it’s got like a tiny little attack surface that’s been abstracted away.

Yeah, I mean, security is certainly one very good reason why people lean towards static websites. There are, yeah, there are others: performance is another good one. A lot of times because the resources and the content have been pre generated. You can push it out to very low resource servers like edge servers or content delivery networks. And it can get to the users a little bit faster, since there’s no processing that needs to be done.

But let’s back up just a minute and talk about what a statically generated website actually is. Yeah, cuz that’s a, so we’ll rewind, kind of back to the very beginning here. And a statically generated website is a website where all of the things that come down to the web browser, to the client, have been prebuilt. That could be HTML. But it could also be JavaScript, it could be images, it could be other resources. Essentially, you take the webserver out of the picture, and you do the work that the webserver would normally do beforehand.

Now, there’s some challenges and tricks to that it’s kind of a different way of looking at things. For one, it means that you have to do the work that the webserver would do, for every possible endpoint and combination of query strings and requests, which is certainly doable. I think people would be surprised how many websites you visit on the modern web that are either wholly or partially statically generated. There are a number of very large scale sites that have lots of dynamic content that are being delivered to you as static resources, kind of in their initial form. Stack Overflow is one that comes to mind. They do a lot of what’s called edge caching, which is a form of static generation where you generate things once and then save it. Amazon statically, generates a lot of their product pages, and then augments those during a request.

Another thing to keep in mind is that a statically generated website does not mean static content, or static user interface. What a lot of people do is statically, generate the web resources, and then create a dynamic API that can be called to populate that. That model is often what’s called the JAM Stack, which you may or may not have heard, and is kind of gaining traction as a term for this sort of statically generated website. The JAM Stack is a stack with the three letters standing for JavaScript, API’s, and markup. And it’s kind of the bare minimum that you would need to create a statically generated site that has dynamic content on it through the use of API’s and JavaScript; essentially moving the processing from what was traditionally on a webserver to the user’s web browser, which solves a lot of problems, right? It’s coming full circle, security being one of them. If you don’t have a webserver, sitting there executing things. There’s there’s no attack surface.

Jamie

Definitely, it’s one of the reasons why I sort of fell in love with the JAM Stack. I’m by no means a security “expert”. But if you show me a way to increase the security of something, or indeed to decrease the attack surface of something, I’m going to be super interested. And when I started hearing about JAM Stack, two-three years ago, I was like, “this is it for me, all of my… any any kind of blog or anything like that,” right? I’m surprised that every time I hit a website that’s powered by WordPress, Ghost, whatever any of these sort of dynamically generated CMS based websites, I can tell when I’ve woken the server up, because it’ll take five or six seconds for it to start responding. I’ll hit the page, and then there’s nothing for five-six seconds. And then it says loading right before I looked at the server and woken up, whereas with a with a statically, generated website, all it’s doing is serving the HTML. And there’s, there’s loads of other stuff that you can do. Like he said, you can make it dynamic, but all it is serving is the HTML. So you there’s nothing to poke and wake up, right. It’s like an nginx, or an Apache server is nothing.

Dave

Yeah, and a lot of times, the web hosts that specialize in hosting static content - the Netlify and the GitHub Pages - those those kinds of web hosts are, they’re often have, you know, 1000s of sites on these highly optimized delivery systems. Whose only job is to check out the endpoint or the route that you’re calling and return back the static content that happens to live at that route. So you can see how that’s both easy to optimize, and removes any sort of security burden off of you. I mean, not that those systems themselves have to be secured. But it’s not your problem anymore there because it’s one system doing one thing, and that thing is very simple. It’s easy for those hosts to then harden those systems well beyond what can be done with a standard style web host.

Yeah, and I think, you know, I think I touched on it earlier. You know, blogs, like you said, that kind of thing is kind of a perfect candidate for static generation. But you know, you can go bigger than that to: really any site where the number of views that a user might look at is well defined and well bounded. could in theory be statically generated. Even if that number is, you know, in the 10s of 1000s, due to, you know, like, factorial style combinations. As long as you can define those combinations, and figure out exactly what the page should look like. You can statically generate it and stick it on a static host. And then augment with JavaScript and API’s as needed.

A pattern I’ve seen is, folks statically, generating JSON files, and then serving those as a static resource, as an API, so to speak. And that then creates all kinds of possibilities. If you’re a statically generated site with statically generated JavaScript, loads your statically generated JSON, and can do things like grids with filtering and paging and you know, the world’s the limit there in terms of your imagination, how you can use that. So there are very few sites that really aren’t possible with static generation. Now, of course, there’s always a trade off to there’s a, how hard is this going to be to statically generate? How many resources will I need to output? When that number gets into like the millions. you start to say, “well, okay, maybe this isn’t practical for this model.” You know, every tool in the toolbox has a use.

Jamie

But like you said, you can augment with - you mentioned filtering, and you know, sorting and paging and stuff - we would do that with JavaScript anyway. And so it’s like, all you’re doing, like. Let’s say you’re, you’re you build a ASP .NET MVC application that shows an e-commerce website, right, and it has a paged list of products. You could have a server that generates that page, you and it generates the paging control, and then you hit “next” on the paging control, and it’s going to make a JavaScript API call and get the content to display on screen. And then it’s going to replace that content, either via a partial or via Blazor, which we’ll talk about later, or via actually using JavaScript and replacing the DOM elements. Well, you don’t need, in that instance, you don’t need the ASP. NET MVC server to show you that page initially. Right? Because you’ve just proven that you can put the request in and get the content to display on screen through an API. So it’s, yeah, the amount of times that I’ve said to people where I’ve been like, “you know, this could be a static website.” And they go, “no, no, no, because I need the interactivity.” And I’m like, “you just can still have that,” you know.

Dave

Yeah, yeah, I think you know, and even when you’re using a JAM Stack model that includes a server with an API, I personally find that splitting my site and my front end bits into this totally separate thing that I can generate beforehand, deploy to a CDN, mirror geographically. The separating that out from my API back end, is a much at least for me, is a much easier to reason about and more elegant architectural design anyway, than having my UI layer and my front end layer mixed in the same app with my back end and my API’s. If I’m just thinking about things kind of gets clarified when when I separate those two things out. And then when you’re separating them out at that point. You might as well look at static generation for the front end if you’re you know, you If you’re in that model anyway.

Jamie

Yeah, absolutely. And yeah, there was something you said, but I completely forgot it. Because you, because what you did was you covered just about what I was about to say. I’m not gonna sit here and waffle on and try to come up with a with an interesting point to make. But you, you’re absolutely right. You know, if you’re if you’re using that JAM Stack idea of talking to a third party API, that’s what I was gonna say. I feel like separating your UI and the generation of the UI and putting that somewhere else and the hosting of that UI, and having your API or API’s separately, well that’s the S in SOLID. That’s separation of concerns, right? “My API lives over here. And my UI lives over here,” that’s an you know, there’s a contract there. This is just an interface for .NET developers, right?

Dave

Well, and I think, you know, particularly in the .NET world, we’re we’re so used to this kind of MVC model where we’re building these very thick client apps. Once you start looking around what third party service providers and API’s exist out there, it’s a little bit of like a mind exploding moment, when you think about how you can leverage some of that. I’ve seen some very, very cool, very dynamic JAM Stack websites built that use something like Google Sheets for their back - you know for their quote, unquote, back end API. Yeah, they stick all the data up in a Google sheet, and then query that using JavaScript to get the data that they need to show on the site. And you know, it’s beautiful, he can go in, you know, as an editor, you go into the Google Doc, and, you know, edit whatever data you need, it’s immediately reflected on the clients because they’re pulling from that in real time. Because that work is distributed to each of the client browsers, using JavaScript, there’s no load balancing issues, you don’t have to worry about the server overloading. So there’s, there’s a lot of, you know, API enabled services out there that are just waiting to be used as data sources and information sources for JAM Stack style websites.

Jamie

Sure, sure. And I feel like we’re just gonna sit there and agree for the next 5-10 minutes.

Dave

Yeah.

Jamie

I feel like using a third party API in a JAM Stack situation, it removes the risk. Okay, so risk is probably not the right word, the responsibility, you said there about load balancing, right? Let’s say I want to use identity over an API, I don’t have to store anything about my users, which means that if I somehow managed to get hacked, there’s nothing about my users in my codebase. Which means, you know, from a regulatory standpoint, I don’t have to worry about being hacked, right. The only thing I have to worry about is perhaps if the tokens get shared, and if the tokens are shared, you would hope that, you know, as a developer, you’d hope that I’d set them up with a short lifespan anyway. So you know, an hour, two hours, you know, maximum sort of thing.

Dave

So yeah, and even things like authentication, there’s, there’s services for that, right? You can go Auth0 or Octa, any of the number of services out there to do it. Let alone doing things like social logins, and just letting other third parties kind of handle that for you. So yeah, I mean, there’s, these days, there is a hosted service for literally anything you could think of. Now, an argument could be made that using 10, hosted services and patching them together is perhaps more complicated than than doing it yourself and your own web server. And that certainly, you know, kind of a personal preference thing. For me, I want as much off my plate as I can get. And so any kind of infrastructure, I don’t have to maintain any additional API endpoints I can eliminate, any code that I don’t have to write, you know, all of that, from my perspective is improvement to quality of life. And lets me focus on the parts that I do need to build.

Jamie

Yeah, absolutely. And especially if you’re like a solo developer, working on a single project, there’s going to be a team of people that there’s other API you’re poking into whose job it is to maintain it. And so they will have 20-30-40 more people than you.

Dave

Yeah. And and secure it and make it fast. First, and you know, and and, yeah, absolutely. You know, why not leverage those people who are doing that on your behalf?

Jamie

Absolutely. You know, it’s like, if you were to walk through a car manufacturing plant, you go to a Toyota or a Nissan or I don’t think there’s that many. I mean, that’s kind of the whole point is like, there’s not many left in America. But if you were to go to a carmanufacturing plant, you will probably find that the cars that are being manufactured, it might be a Toyota you’re looking at, we might have a Ford engine in it, right? Because they’ve relied on Ford to put the engine together in such a way that it makes sense. And so sometimes, you know, you just grab the bits, not necessarily off the shelf, but grab the other bits that people have made because they have the expert knowledge, right?

Dave

Yeah, yeah, exactly.

Jamie

Cool. So I’ve feel like we’ve talked a whole bunch of our JAM Stack so far. I feel like we talked a little bit about how that differs to sort of like a standard ASP. NET MVC website. But what about - ad I’ve heard this phrase, and I love it - the BAM Stack. Blazor, API’s, and Markup. How does that like, there’s almost just like a semantic difference, isn’t there between BAM and JAM, right? Because…

Dave

Yeah, so I’m glad you brought up Blazor because Blazor is very, very interesting. In both in terms of just a raw product - I love the experimentation going on there. But also in terms of how it contrasts to kind of our traditional JAM Stack. You know, if going back two years to the invention of JAM Stack is traditional - tech moves fast.

Yeah, so Blazor kind of operates in a few different modes, right? I mean, there’s the server side Blazor mode, where it creates this open pipe, and sends DOM updates and rendering commands to the client from a server; that is absolutely not static or JAM Stack, or anything, right. You need a heavy server that is kind of almost mirroring the clients browser in this stateful manner that knows what that browsers seeing, and can compute the differences in the DOM descend down to light it up and make it change the way you want to. Nothing wrong with that mode. And I think it’s just brilliant, the way it works, and the ideas and architecture behind it. But that’s not what we’re here to talk about. Right? We’re here to talk about statically generated things and JAM S and BAM Stack.

So when we talk about Blazor, in static generation contexts, what we’re talking about is the client side Blazor mode. And that’s the mode where the .NET Blazor compiler will take your blazer application and create a[n] assembly from it. And then also create and output a bunch of bootstrapping stuff. That includes some JavaScript files that help initialize web assembly that load up the .NET runtime. And then that load your Blazor assembly into memory on the browser. And I just said a bunch of like really buzzwordy buzzwords there. So if anyone’s not familiar with it, what’s happening here, kind of less buzzworthy sense is that: there’s this technology that exists inside browsers now that can run kind of arbitrary computer code, right? We’ve always been able to run JavaScript in the browser kind of as far back as ever browsers. And JavaScript is a specific language, and you write it and it shows up in text that get sent as text, usually down to the browser. The browser reads it, compiles it, and runs it, right. And that’s kind of the model we’ve always had.

But now there’s this thing called WebAssembly. And the idea is that we’re gonna swap out that piece of JavaScript that does the work and replace it with - or add alongside it - a little virtual machine that can read and understand machine code; almost like assembly code, that’s why they call it WebAssembly. And so when we do that, the idea is essentially the same: I want to send some kind of logic, some kind of programming code, to the browser; but instead of that code having to be JavaScript, I can now send it code that came from any language that is at a kind of a lower level and this WebAssembly thing that lives inside the user’s browser knows what to do with it and can run it.

So kind of coming back to Blazor, in this client side mode of Blazor, the .NET compiler takes your your Blazor app, compiles it all into a standard .NET assembly, and then rigs up the extra stuff, so that a client’s web browser using this WebAssembly bit that’s in there, can load up the .NET runtime, and then load up your Blazor app from its assembly and run that directly in the browser. So in a lot of ways, it’s not all that different conceptually, from sending down a JavaScript file to the browser, right? You’ve got maApp.js, that’s pretty typical in SPA applications, for example. This is kinda like that. It’s just instead of .js, it’s a bunch of .wasm, and .dll files.

And so when you start thinking about it that way, your Blazor app becomes your statically generated application. So I think it’s you know, it’s funny, we talked about how - and we’ll talk about Statiq in a few minutes, and how that’s a static generator for .NET - but it’s easy to forget that .NET now already has a static generator. It just happens that the static generator that’s built into the platform is built around this sort of WebAssembly technology.

Jamie

Yeah, it’s a it’s an interesting time for technology, for sure. And like you say, it’s, it’s about using the tool that’s in the toolbox that fits the solution best. Because like no tool will fit the solution perfectly. Because that’s how development works. Right? And so…

Dave

Yeah, and yeah, like you said, BAM vs JAM it’s the same thing. We’re just swapping out the JavaScript parts for Blazor parts, but we still have to make API calls from the client. Because now we’re living on the client. We’re not living behind the firewall on your web server somewhere we’re living on the client. And that is the context from which everything is happening. So we still have to make API calls to get data. You know, we still have to get the markup that kind of hosts our Blazor, app and bootstraps everything. We can use third party API’s, just like we could from a JavaScript context, we could call our own API’s just like we could when JavaScript was on the front end. So in the BAM Stack you’re essentially just swapping out JavaScript for for C# or .NET code.

Jamie

Yeah, definitely. I feel as though it’s something that you haven’t mentioned yet. But I feel as though it needs to sort of be mentioned is: because obviously, you’re pulling down the .NET DLL that the Blazor compilation process has created for your app, it has to pull that down, and the supporting libraries, and the runtime, right. So whilst it is a static app, in the same sense that it has been generated ahead of time, I feel like my personal preference is still to use JAM Stack, because BAM Stack requires this huge amount of data to be downloaded to your browser. Now, admittedly, once it’s downloaded, it’s cached. So there’s only that one time hit of downloading 17 megabytes of DLLs, 18 megabytes of DLLs, 11.9 megabytes if you’re using JSON .NET - is a huge amount of data to pull down, depending…

Dave

Yeah, I know, the team keeps working on things like tree shaking to remove code that you’re not using from that compilation. But yeah, it’s gonna be big, the .NET runtime is big. And so yeah, it’s again, it’s a toolbox thing, right? I mean, even within the concept of statically generated apps, we’re kind of narrowing down into which kind of static generation is appropriate for which use case. A Blazor app may be the perfect answer for that line of business app that you want to deliver to your global business user base through CDNs on the edge, but that everyone is kind of on maybe they’re on on Azure VNets, and so they’re close to the source and downloading 20 Meg’s to the web browser in their VM that’s on the same network is not a big deal. But downloading 20 megabytes of website to someone in Sydney, Australia, you know, maybe a bigger deal. So yeah, I mean, it’s, again, it’s kind of, you know, trade offs are everywhere, right?

Jamie

Yeah, if you perhaps if you’re shipping a device that is having this app on it, you could pre load the app, and the runtime and everything, you do that request once whilst it’s in your data center, in your manufacturing plant, and then you send it out. And then the updates will be small, right? Because it only needs to pull down, every time you push up an update to the code, it’s only really going to be your code that changes. And so the two/three megabytes of code that you’ve written, that has then been tree shaked will be downloaded, right? The runtime won’t be redownloaded. And your supporting libraries unless they change won’t be redownloaded. So if you can do that, take that hit of pre loading it onto a machine before you send it out. But then, you know, if you’re doing something on the web, you’re not probably pre loading on a machine like in a kiosk and giving someone the the app.

Dave

Right, yeah.

Jamie

Okay, so let’s, let’s walk away from ASP .NET for the time being, because we spend a lot of time on that. So I happen to know that there are a couple of different static website generators. And we’ll come on to this in a minute. But Statiq doesn’t just do websites or it can statically generate a whole bunch of stuff. I’m kind of giving something away for the listeners.

Dave

Yeah, okay, you’re ruining the, you’re burying the lead. You’re ruining the surprise. We’ll get there.

Jamie

A little tease, little tease, keep them interested. You know, my voice is so boring and laconic. But yeah, so I know there’s Jekyll, Hugo, Gatsby, those are three of the big ones. And obviously, Statiq makes it one of the four of the big ones. But okay, so I know that Hugo uses the Go programming language, we don’t have to do any programming to get it working; Jekyll and Gatsby JavaScript based and you have to pull like, Okay, I’m not gonna make the joke, but you have to pull a gigabyte of JavaScript dependencies did to be liquid, you got to do NPM install.

Dave

Yeah, well, Jekyll is actually Ruby, which is like, if you think npm install is bad. You know, getting the runtime up for Jekyll is kind of notoriously difficult. I mean, it’s not that bad. But but you know, it’s it’s a whole separate tool chain that someone like a .NET developer may not have on their machine and readily available.


A Request To You All

If you’re enjoying this show, would you mind sharing it with a colleague? Check your podcatcher for a link to show notes, which has an embedded player within it and a transcription and all that stuff, and share that link with them. I’d really appreciate it if you could indeed share the show.

But if you’d like other ways to support it, you could:

I would love it if you would share the show with a friend or colleague or leave a rating or review. The other options are completely up to you, and are not required at all to continue enjoying the show.

Anyway, let’s get back to it.


Jamie

So okay, with Statiq being .NET. Why would - I hate the “why” question, because it always comes across as really aggressive. But I’m afraid to say this in a little floaty way: why would I use Statiq instead of Jekyll or Hugo or Gatsby?

Dave

Yeah, no. it’s a fair question. It’s a good one. You know, why does this thing even exist in the world? Right? I mean, people undertake open source projects for a variety of reasons. Some are to learn, which is kind of house Statiq started in its previous form, six years ago now. Gosh, it’s hard to believe it’s been that long. Yeah, and some are kind of started to fill a gap and functionality or feature set, which is kind of the second reason I started working on static generators.

So why you know, why this project? Why does it exist in the world? And the answer is really twofold. And both reasons are kind of equally important. The first is that I know razor and I like razor. And when I build a website, I want to use razor. But I also really, really like static generation and have way before Statiq was even a glimmer in my eye. I just I really liked the concept. I like how much it removes off my plate, right? You get to a point when you have just too much to do, you know, we can’t build all the things we want to build. And so any tool or any concept that eliminates things from my “stuff I need to worry about” bucket is kind of vastly interesting to me. And so static site generation like immediately fills that kind of thought process, because it removes this entire class of web app problem in terms of setting up a web server, deploying it and all that, that you just don’t even think about anymore.

So and you know, uptime making sure it doesn’t go down. The number of times, before I really got into statically generated websites that, you know, I would get an alert that like 9pm at night, or 10pm. You know, as I’m trying to enjoy my evening, that my web server is suddenly offline, I haven’t seen one of those in six years. So yeah, that was kind of the first pitch. I liked static generation as a concept. But I like .NET and in particular, razor is a templating language. And at the time, there was no way to marry the two. So I set out to make a way of turning razor templates, and particularly razor layouts, into websites without having a web server involved.

But the kind of second reason, that probably would not have been enough alone to keep me going, as long as the project has been going. What really kind of turns into a bit more than just turning razor into HTML is, I looked around and did not see the kind of static generator in any language that I would want to use. And what I mean by that is, most static generators are, in particular, static website generators, and their entire purpose is to take a set of markdown files, along with a layout written in whatever language du jour that particular platform supports. Sometimes it’s handlebars, sometimes it’s moustache. Sometimes it’s liquid, which I really like. But it’s to take markdown files, and these layouts and turn them into HTML. And maybe do some other stuff to your resources like minify, your JavaScript, or nowadays, they’ve gotten a little more sophisticated and can do things like making JavaScript bundles, and calling out to Webpack and yarn and things like that. But they’re entirely focused around this single concept of turning web stuff into static web stuff. Which is fine, and Statiq can do that, too.

But what I did not see was a way to sort of easily introduce or augment that process with other processes that can get data from different places and produce data in different ways. What I mean by that is, let’s say you have, as an example, a set of content sitting in a SQL database somewhere, maybe that’s got your blog posts in the database, or maybe it’s got a database of products and prices. With most of the existing static generators, at least at the time, pulling from those kinds of resources and using that data in the pursuit of building your statically generated web app was difficult. I mean, you could do it by writing a lot of code. But they weren’t really designed to do that. So static is kind of my answer to that problem. It’s how do you build a static site generator, that that can do, you know, the happy path is easy. It can do the same stuff that your Jekyll or your Hugo can do without really any effort on the part of the developer. But now, we’re .NET developers, so we want to tinker, right. That’s kind of Microsoft’s whole ethos. And we kind of inherited as .NET developers, right. So as a .NET developer, I want to tinker with this, I want to introduce things, I want to use this as a toolkit to build my own static generator that can pull data from wherever it needs to pull data from; that can mix and match data, however it needs to; that can splice data up and mix it together; and do all those things in a way that is kind of easy to think about and visualize.

So that is really the sort of ideas are in marketing because I’m not marketing to anyone. But that’s the marketing pitch, right? That’s the elevator pitch. Is it’s a static generator that is designed mostly for developers, as a toolkit to build your own static generation capabilities that do whatever you need them to do. That’s turned out to be pretty powerful, right? I mean, bloggers use Statiq, we’ve got a lot of people using it for their blogs. And they don’t really tweak it at all, they add the five or six lines of boilerplate code to their app, and they’re ready to go. And they never touched the app again, and they just use it to generate a blog from their markdown. And that’s totally fine. But when you want to go beyond that, it’s designed to be familiar, and robust enough to do so.

Jamie

Okay, so what kinds of things are we talking about? So you said, you know, that Hugo, Gatsby, etc., they’re all really good at a developer taking this content, which exists on disk in a form that it knows about, and creating essentially a website from a whole bunch of hierarchical HTML with links everywhere, and filling all that data in? But what can I do with Statiq then? I know I sort of, I teased a little earlier on and you’ve said a few times, but like, like you said one of the things you can do is create a blog, create an HTML website, what else can I do with it? Right?

Dave

Yeah. So a great example of the class of problem that’s kind of solved by this is some of the work that’s been done by folks at both Kentico and Contentful. Both of those are CMS services, sometimes called headless CMSs. The idea being that they’re a content management system that has no front end, it’s got no web app that a user hits. You know, think about a good metaphor would be like WordPress, but without the WordPress site, just the admin interface. That’s the idea behind a headless CMS. And these headless CMS is are popping up everywhere, it’s a fantastic model, because what it does, is again, it helps separate these concerns. And it makes it easy to author a maintain content and resources, both by the developer but more importantly, by non developers, maybe your marketing team, maybe your business users, whoever. You know, it provides nice interfaces for those people to come in and work on the content of your site in an admin interface. And then it provides that content through API’s, right. So again, this is getting into API’s involved in the static site world.

But in this case, it’s a little bit different flavor, because we’re reading the API’s at generation time, as opposed to at runtime using JavaScript from the client. In this case, we’re going to go out and our static generator is going to go talk to these API’s while it’s generating the site. And when it’s talking to these API’s, it can pull down that content that was written inside of that headless CMS. So there’s already, like I said, there’s two really great proof of concepts out there that are in use today. Kentico has kind of really done a fantastic job going down that road. They even have their own little microsite that we’ll add to the show notes, that sort of demonstrates how to mix a headless CMS with Statiq; Contentful also has some some work out there doing the same.

And because you know, kind of coming back to the original question, because Statiq is designed for this kind of thing, mixing in your own headless CMS, whatever service you’re using with Statiq by making those API calls within your Statiq app is relatively straightforward. You make the calls, maybe using that company’s .NET API, maybe just using normal RESTful web calls through an HTTP client. You make those calls, you get the data, you tell Statiq to use this data going forward, and then downstream bits can pick that up and run with it. So maybe you feed that data into a razor layout. And now all of a sudden, the pages you made inside your headless CMS, get spit out by static as HTML files wrapped in your razor layout.

So that’s a fantastic kind of case in point there. But there’s others, for example, the speaker directory of the .NET Foundation website uses Statiq, and in that case, speakers create their profiles as yml files inside the .NET Foundation GitHub repo. And the yml file defines the speaker’s name, their web links and some detail information, their image if they want one. And then every time something new gets committed to that repo, GitHub actions goes out, runs statiq, rebuilds the .NET Foundation website, and updates all of these statically generated resources that power the speaker directory. So when you’re browsing the speaker directory, on the .NET Foundation website, you’re looking at a set of statically generated resources, including a JavaScript file in the back end that’s powering the display and filtering. That was all generated on every commit by GitHub actions and immediately updated each time the site is updated automatically.

So yeah, there’s a lot that you can do, when you kind of unshackle what the static generator is capable of. And in keeping in mind with the fact that .NET developers and we’re probably all familiar with ASP. NET as a platform, Statiq tries to follow the same patterns. The fluent configuration should be familiar to anyone who’s ever worked with a, you know, ASP, .NET Core startup file. The dependency injection uses the, you know, the inbox .NET. Dependency Injection container, logging uses the built in .NET logging stuff. So it’s designed to feel familiar. And to… I always try and keep in mind, “what would a static generator look like if the ASP .NET team were to build one”? And that’s kind of what the user experience I’m going after is.

Jamie

Right. Okay. So let’s talk about how I use it then. Right. I’m coming at this conversation specifically from the static generation side of it, and from having used Hugo. Just a look behind the scenes, the website for The .NET Core podcast is built by Hugo; the website for Waffling Taylors, which is another podcast that I work on, built by Hugo; Tabs and Sapces, built by Gatsby. So there’s a couple of different, they’re all… my understanding of how they work is I guess, you download a thing. And then you find that thing, all your content, and a website comes out the other end. So I’m downloading statiq.exe, right?

Dave

No, so yeah, you, you asked the exact perfect question. So we’re playing baseball here, you did the pitch, now I’m gonna knock it into the stands. No, you don’t download statiq.exe, there is no static.exe. There is no application to run. There’s not even a .NET tool, you know. Statiq is a framework, which means that you include it in your own application in your own console app.

So you make a console app, you import the Statiq NuGet packages, depending on whether you want the kind of lower level framework, or you want some additional capabilities layered on top of that for things like websites, or even API documentation. You bring in those packages. And then you you write, at a minimum, I think it’s down to like two or three lines of code in the entry point to your console app. And those two or three lines of code, bootstrap the whole thing. So in that sense, it’s not unlike creating a ASP .NET Core website, right? You you create the console app. And there’s a little bit of bootstrapping code in there to rig up the web host and get it going. This is kind of similar.

But what that does for you, is even though the kind of basic level Statiq app is… are… those are all gonna look exactly the same. They’re gonna have this exact same three lines of code. But because you’ve got those three lines of code, and you’ve got that app. Now, it kind of encourages, and makes it easy to add more to do more. You want to change settings, maybe you want to change the title of the site. You can do that using configuration files, but you can also do it straight in your code. There’s all kinds of stuff that you can do now that you’ve got that kind of fluent bootstrapper in your startup method.

Jamie

Right? Okay. So you’re talking about how it’s a NuGET package, you pull it in, it creates this almost like a, like you say, a fluid readable API, as you read through it. I hit f5. App pokes at my content…

Dave

And maybe.. Yeah. So there’s, yeah, there’s different flavors of Statiq, right. So there’s Statiq Framework, which is a very low level thing, which has all of the building blocks, think of it as your set of Legos. Hopefully, you don’t get sued for my use of a trademark term here. But your Statiq Framework is your your static generation Legos. And you can pick and choose whatever blocks you want for the kind of generate you’re trying to build. But nothing is built for you, you’re getting a box of unconnected Legos. So if you create an app, using Statiq Framework, and don’t do anything else, but set up the bootstrapper, and hit go, nothing will happen. I mean, it’ll run, it’ll tell you, “I didn’t do anything, because he didn’t tell me what to do.” So Statiq Framework is very good for scenarios where you want the most amount of control, you don’t want extra stuff or fluff. Let’s say all you want to do is turn five markdown files into HTML, you don’t need anything more than another five or six lines of code, and undefined to do that. So that would be a good choice for that scenario. But you have to do the building.

You can even use it to do things that are completely unrelated to web apps. ’ve seen it used as a like a build tool, or an orchestration tool. Because at its core, Static operates on this concept of pipelines and pipeline dependencies. And it helps with like ordering and concurrency and concerns like that. So that’s Static Framework

Now, if you want it to do some stuff out of the box without writing code, now we’re into a layer sitting on top called Static Web. And Static Web takes all those Lego bricks, and assembles them for you into a set of… I think there’s eight or nine pipelines that are in there and do different things. What do some of those do? Well, some of them convert your markdown to HTML. Some of them create archives like that tag listings, or by date archives, that kind of thing. Some of them, go through and read yml and JSON files and make that available to your pages as they’re being generated. Some of them minify your resources. You know, so there’s this set of kind of pre built features and pipelines that come along with Static Web. So if you want to write a blog, for example, you can import the Static Web NuGet package, write your three lines of bootstrapping code. And now, instead of having nothing to start with, you’ve got a entire static generator that is not dissimilar from Hugo, or Gatsby, or Jekyll, or Eleventy, or whichever ready to go. And it’s now kind of in your app. And you can still augment that, change it, modify it with your own code and pipelines, just like you could with framework, but the groundwork is done for you if you’re working on websites.

And then even the layer on top of that is a project called Static Docks, which does everything Static Web does an add support for reading C# source files or assemblies, and creating API documentation from those. Think kind of like Sandcastle. So you know, there’s different flavors of Static that layer on additional functionality depending on how much you want done for you versus how much you want to do yourself.

Jamie

Okay. So leftfield question based on what you just said, Can static document itself?

Dave

Yes, the static.dev API section is generated by Static. self documenting, it is not quite as scary as self aware, but still scary.

Jamie

I like it. See, that’s always been something that’s been difficult for me in previous years, when I’m working with a client or back when I was a permanent employee, when it was like, “right, how are we going to document how this works?” And someone’s been like, “yeah, well, we’ll just put loads of XML documentation in it. And then you just have to pull the code and read it.” And I’m like, “okay, that’s great. But what if you’re not a .NET developer, and you want to know how our API works?” And this was back in the days before Swagger and Open API, and they were like, “yeah, what we’ll do is we’ll put XML documents in it. And then we need to need to pull the code and read it.” Like, “well, you just said exactly the same thing twice. doesn’t solve the problem.”

Dave

Yeah. So Static Docks was built kind of to scratch this itch I had where I looked around, and there really wasn’t a good modern option for .NET API documentation. I mean, there’s Sandcastle, which still works. And it’s still a good tool. I used the heck out of it back in the day. But I didn’t feel like it was flexible enough for modern .NET documentation sites, at least the kinds of sites I want to build; to kind of mix the one platform to mix the API docs with my content, and kind of have those cross referenced and linking back and forth and things like that.

You know, you see a Sandcastle site, which looks fantastic. But most of the time, when you see that kind of generated document, there’s there’s a few other tools that that work similarly, you know, you’re on the site, and then you hit the API link in the nav bar, and whoa, all of a sudden, you’re on like a completely different site. And there’s no continuity between the two. So I didn’t love that. And that was one of the reasons I wanted to kind of get API documentation generation in here. Because I felt like that was a missed opportunity to have your guidance, your plain language documentation, and API documentation living in the same sort of universe.

And now, we also have DocFX, which is a fantastic project. And I think those folks are doing great work. But it - as a project - it’s tailored towards powering the Microsoft documentation. And so there’s trade offs there. I mean, that is the team’s focus. So powering arbitrary .NET projects is not really their core focus and constituency. And it shows a little bit in the onramp. So you know, it’s it’s very similar DocFx is very similar to Static Docks, in terms of conceptual, the way that they go about things and the thinking there. The experience, though, is a little bit different. And that’s not to say one is better than the other. And they both have strengths and weaknesses. But you know, I… looking around, it was like, “well, shoot, I have all these open source projects, and I really want to easily generate API documentation for them. And I’ve got this static generator I’ve been working on, you know, what’s an open source developer to do?” And the answer is, you know, always, “I’ll make a new open source project,” until you’ve got, you know, 10 of those on the backburner that you’re never going to get to. Thankfully, I got to this one, and now it’s available for your use.

Jamie

Excellent. Okay. So since you said - and here’s another curveball based on what you’ve just said, right. I hope I’m using the baseball analogies correctly.

Dave

I know a little bit of a talk about localization. Yeah.

Jamie

You said that Statiq is based on this idea of pipelines and this fluent API chaining things together. Thought experiment: would it be possible for Statiq not just to document .NET libraries, but maybe to look at a JavaScript library and document that or a suite of say, Ruby gems or, you know if someone could write the code that inspects those binaries inspects the documentation, could Static just swap that Lego piece over. And hey, we’ve just documented the JavaScript library. We’ve just documented Java library or something.

Dave

Yeah, absolutely. Yeah, that would be a fair amount of work. Because there’s kind of two sides to API documentation. There’s the semantic modeling, which is understanding what the code looks like what it contains the control flows. In .NET. We have Roslyn, which is, you know, just a gift from Microsoft to all of us. It is fantastic. So we really have a head start in that regard. There are similar semantic analysis tools for other platforms. They don’t necessarily integrate with .NET, though.

So Statiq has modules that help with that, too. There’s one particularly powerful module, whose entire job is to shell out and start a new process. And then either let it run, or watch it, or wait for it to send information back. That acts as kind of a glue between what’s going on inside your .NET app that’s running Statiq, and the rest of the universe. So we have users who, for example, use that to launch webpack when they start to build their website, or launch tailwind the tailwind compiler, or you can launch whatever arbitrary stuff you want to launch with that.

So with that piece as glue, you could see a world where you go off and launch some semantic analysis tool, and maybe you even find one in the .NET world; maybe there’s an assembly out there on NuGet that knows how to read and parse, say, Ruby code and can spit out a semantic model for you to use. However you get it, the first step is getting that semantic model, right? So Statiq helps in that sense by kind of providing the the framework in which you can make that work happen in the right order.

And so once you’ve got that semantic model, now, the second part of that problem is, “how do I spit HTML out from that?” So the theme that Statiq Docks ships with is sort of heavily dependent on Roslyn’s view of the world. It essentially has a bunch of razor files that take the static representation of the symbols that Roslyn produces for .NET code, and turns them into bits on the page. So that you have this beautiful API documentation that lists your symbols and your methods and your properties and the documentation for that. So any effort to document some other language would need to have a different set of layout files that are kind of appropriate for the kind of information that that semantic analysis piece produces.

So that’s how you would glue things together. Now, the good news is that doing that kind of gluing together and making those kinds of completely arbitrary, “we never would have thought of it ourselves,” sorts of things happen within your static generator, is exactly what Statiq was built to enable. So I would venture to say that to do that would take some work, but the work you’re doing would be almost entirely focused on that specific problem: parsing and analyzing JavaScript code and producing a good theme and output from it. And not at all on the problem of, “how do I fit this into my static generation process?” Which if you were to do it in pretty much any other static generator, that second part, which Statiq kind of removes from you, by making it easy, would be a good chunk of your effort trying to figure out well, “how do I get Eleventy to go out and run this arbitrary code that reads JavaScript and analyzes it and produces output that I can then use in my layout? " You know, I would have no idea where to begin with that. I’m sure there’s some Eleventy wizards who could figure it out. But Sadek is designed specifically to answer those kinds of questions.

Jamie

Okay, okay. I mean, yeah, So like I said, it was a thought experiment bit of a curveball. And it sounds like the, like you said the the difficult bit of displaying it and, “how do I put this into my static generation?” bit is taken care of. The domain problem of reading a binary, or a library or some code by some other thing, that’s the bit that you would focus on. Right? You said that, right. So let’s say I go away, and for six months, I wrote a way to read JavaScript code in .NET, and parse it, and figure it all out, and create, “the ultimate way to dissect JavaScript code in .NET,” and I create a little… a couple of pages that describe the theme. I just literally plug that into Statiq, and give it a binary and or give it some code. And it should just - thought experiment - it should just work. I’m not saying…

Dave

Yeah, and ideally. Yeah, everything. So Statiq is also built to be very modular. So ideally, everything is built in such a way that, you know, if one wanted to, it could be released as a project in its own right, as a Statiq extension, and then used by the community. And from that point forward, anyone could produce documentation for their JavaScript library, using Statiq right alongside all the other stuff they’re doing in Statiq.

A great example of this kind of thing: there are several open issues that I just haven’t gotten to yet to do something similar for Swagger - or I guess now, it’s Open API documentation - to look through a set of endpoints or a Open API spec, and produce statically generate a nice web site that that documents that Open API spec. That’s a perfect example of where Statiq kind of comes in and is ideal for that job. And once that work happens, once that the code is written to create a module that can read an Open API spec and produce appropriate Statiq documents for that, and a theme is written that can take those documents and turn them into nice looking HTML, that then becomes available for everyone. So that yeah, that’s the dream. That’s the hope. So yeah, I mean, having Statiq document other kinds of programmatic artifacts is definitely sort of in the realm of things we think about.

Jamie

Okay. So what I’ll say is what we’re coming up on the end of our time together. I’d love to have you back and talk a lot more about this, because there’s so much more that we could talk about, if you’re interested in coming back and talking to listeners more, because this is just a it’s a topic, which is just so open for discussion. And there’s something that I’ve got in our notes that, you know, “people talk about static websites is not changeable. And it’s like, well, yeah, but I got zero downtime”. And I don’t have to do Kubernetes, Docker, microservices, something something scalable, something something, alphabet soup, and huge amounts of complicated technology to do that. But I feel like we could probably park that conversation, whet everyone’s appetite. And maybe if you’re interested, we can come back and talk about that.

Dave

Oh, absolutely. Yeah. So everyone, you heard it here. Sit tight for part two coming to a podcast near you at some point in the future.

Jamie

Absolutely. Okay. Well, no, that’s great. That would be wonderful to do. Because I think I think there’s a great conversation about that about how most developers leap towards the complicated first, because maybe we’ve been - I can’t think of the word but we’ve been sort of like conditioned, that’s probably the wrong word to use. But it feels like it’s kind of right-ish. We’ve been conditioned to leap towards the most complicated solution possible, and then build that. And it’s like, “well, no, because like, the websites a static website. It’s just HTML. You don’t need anything more than that.”

But yeah, that’s that’s whet the listeners appetite and come back to that as another conversation if you’re interested.

Dave

Yeah, totally.

Jamie

Awesome. Because yeah, I feel like that’s something that we could talk about. But yeah, before we go, though, what about if you let the listeners know, maybe how they can get in contact with you? Maybe like if you’re on Twitter or whatever, where they can discover Statiq and learn more about it. And I’ll make sure to collect a whole bunch of links from you put them in the show notes. So then people can just click that right and just, “oh, there’s Dave,” click that; “oh brilliant, that’s Statiq.”

Dave

Yeah, sure. So the main place you can find me is hanging out on Twitter. I’m @DaveAGlick on Twitter. Same thing on GitHub, and really anywhere else, you might find that handle, it’s probably me. You can find Statiq at Statiq.dev. That is the main Statiq website. And then it has links off to GitHub, and has the guide, [and] has the API. So that’s a good starting point for learning about Statiq.

Jamie

Excellent, excellent. Well, like I said, Dave, it’s been an amazing chat with you. I had a wonderful - so really quick look behind the curtains: we do a discovery call first, and we ended up talking for like, almost two hours just in the discovery call. I remember that. That was a lot of fun. And this has been a lot of fun, too.

Dave

Yeah, I think maybe we touched on the first 15% of topics here. Yeah.

Jamie

Absolutely. But you know, let’s because you’re a very interesting guy. And it’s a very interesting topic. And let’s come back again, and do it again.

Dave

Sure.

Jamie

And cover some more points if you’re interested. Excellent.

Well, thank you ever so much for being on the show, Dave. It’s been a real pleasure to talk to you. And I know, I’ve learned a whole bunch of stuff. I’m sure the listeners will do. So. Thank you very much.

Dave

Yeah. Thanks for having me. And if anyone listening to this has questions as you’re listening. Yeah, go ahead. Feel free to reach out to me on Twitter, that’s kind of what I monitor the most. And I’m happy to answer or, you know, just discuss some of the stuff with anyone who’s interested.

Jamie

Awesome, awesome. Thank you very much, Dave.

Wrapping Up

That was my interview with Dave Glick. Be sure to check out the show notes for a bunch of links to some of the stuff that we covered, and full transcription of the interview. The show notes, as always, can be found at dotnetcore.show, and there will be a link directly to them in your podcatcher.

And don’t forget to spread the word, leave a rating or review on your podcatcher of choice - head over to dotnetcore.show/review for ways to do that - reach out via our contact page, and to come back next time for more .NET goodness.

I will see you again real soon. See you later folks.

Follow the show

You can find the show on any of these places