Why Svelte is converting TypeScript to JSDoc

#​638 — May 11, 2023

Read on the Web

JavaScript Weekly

The JavaScript Ecosystem is Delightfully Weird — There are plenty of examples of how JavaScript is weird but Sam focuses on the why. If you’ve been a JS developer for many years you’ll have seen it go through many phases and morph to fit its environment. Sam paints the big picture, concluding with a talk Dan Abramov gave yesterday called “React from Another Dimension.”

Sam Ruby

The New JS Features Coming in ECMAScript 2023 — The next JavaScript update brings smaller additions familiar from other languages, but there are more significant developments waiting in the wings. 

Mary Branscombe (The New Stack)

Full Stack for Front-End Engineers with Jem Young (Netflix) — Learn what it means to become a well-rounded full-stack engineer with this hands-on video course. You’ll dive into servers, work with the command line, understand networking and security, set up continuous integration and deployment, manage databases, build containers, and more.

Frontend Masters sponsor

Vue 3.3 ‘Rurouni Kenshin’ Released — Named after a popular manga series, the latest release of Vue is focused on developer experience improvements, particular for those using TypeScript.

Evan You

John Komarnicki says ▶️ Vue 3.3’s defineModel macro will change the way you write your components.

Next.js 13.4 Released — Despite the minor version bump, this is a big release for the popular React framework. The new app router and its improved approach to filesystem based routing is now offered as a stable feature, with a new concept of server actions being introduced in alpha as a way to mutate data on the server without needing to create an in-between API layer.

Tim Neutkens and Sebastian Markbåge

⚡️ IN BRIEF:

???? Svelte is converting from TypeScript to JSDoc (example).. sort of. Rich Harris popped up on Hacker News to provide some all important context but the ultimate result will be smaller package sizes and a better experience for Svelte’s maintainers.

React now has official ‘canary’ releases if you want to use newer features than in the stable releases but still be on an officially supported channel.

Newly released Firefox 113 lets you override JS files in its debugger.

No stranger to controversy, Ruby on Rails’s David Heinemeier Hansson (DHH) tweeted: ???? “TypeScript sucked out much of the joy I had writing JavaScript.”

RELEASES:

Glint 1.0 – TypeScript powered tooling for Glimmer / Ember templates.

Elementary 2.0 – JS/C++ library for building audio apps.

???? Articles & Tutorials

ES2023’s New Array Copying Methods — The newest ECMAScript spec introduces some new methods on Array that you’ll eventually find useful in your own programs. Phil gives us the tour.

Phil Nash

Private Class Fields Considered Harmful“As a library author, I’ve decided to avoid private class fields from now on and gradually refactor them out of my existing libraries.” Why? Well, that’s the interesting part..

Lea Verou

▶  I’m Done with React — Going from least-to-most important, the reasons this developer isn’t choosing React for future projects make for interesting watching, particularly if you too are overwhelmed by upheaval in the React world. Solid is one of the alternatives he has warmed to.

Adam Elmore

Constraining Language Runtimes with Deterministic Execution — Explore various challenges encountered while using different language runtimes to execute workflow code deterministically.

Temporal Technologies sponsor

Running JavaScript in Rust with Deno — Deno’s use of Rust makes it a natural choice if you’re building a Rust app and want to integrate a JavaScript engine.

Austin Poor

Regular Expressions in JavaScript — Powerful but often misunderstood, many will benefit from this roundup of the potential regexes offer to JavaScript developers.

Adebayo Adams

How to Measure Page Loading Time with the Performance API — The Performance API is a group of standards used to measure the performance of webapps supported in most modern browsers.

Silvestar Bistrović

How to Build a JS VST or Audio Unit Plugin on macOS — VSTs and Audio Units are both types of audio plugins for audio editing software and they’re usually built in C or C++. This tutorial doesn’t dig into the audio side of things, but more the practicalities of packaging things up to get started.

Chris Mendez

An Introduction to the Bun Runtime — If you’ve not yet played with the newest entrant into the JS runtime space, this is a high level overview.

Craig Buckler

2023 State of the Java Ecosystem

New Relic sponsor

Configuring ESLint, Prettier, and TypeScript Together

Josh Goldberg

DestroyRef: Your New Angular 16 Friend

Ion Prodan

Why Astro is My Favorite Framework

Ryan Trimble

???? Code & Tools

file-type 18.4: Detect the File Type of a Buffer, Uint8Array or ArrayBuffer — For example, give it the raw data from a PNG file, and it’ll tell you it’s a PNG file. Uses magic numbers so is targeted solely at non text-based formats.

Sindre Sorhus

Learn How the Rising Trend of Malicious Packages Can Affect Your Apps — Keep your applications secure with Snyk’s article on the increasing number of malicious OS packages and ways to mitigate these risks.

Snyk sponsor

Livefir: Build Reactive HTML Apps with Go and Alpine.js — Go isn’t a language that often pops up in the context of the frontend, but this is a neat integration between Go on the backend and Alpine.js up front.

Adnaan Badr

JZZ.js: A Developer Friendly MIDI library — For both browsers and Node, JZZ.js provides an abstraction over working with MIDI related concepts. There are many examples, but the easter egg in the top left is our favorite.

Sema / Jazz-Soft

htmlparser2 9.0: A ‘Fast and Forgiving’ HTML and XML Parser — Consumes documents and calls callbacks, but it can generate a DOM as well. Works in both Node and browser.

Felix Böhm

cRonstrue: Library to Convert cron Expressions into Human-Readable Form — Given something like */5 * * * *, it’ll return “Every 5 minutes”. No dependencies.

Brady Holt

Knip: Find Unused Files, Dependencies and Exports in TypeScript Projects — Being Dutch for “snip” is appropriate as Knip can trim away things that aren’t being used in your project.

Lars Kappert

jsPlumb 6.1
↳ Visual connectivity for webapps.

gridstack.js 8.1
↳ Build interactive dashboards quickly.

???? Jobs

Find JavaScript Jobs with Hired — Hired makes job hunting easy-instead of chasing recruiters, companies approach you with salary details up front. Create a free profile now.

Hired

Team Lead Web Development — Experienced with Node, React, and TS? Join us and lead a motivated team of devs and help grow and shape the future of our web app focused on helping millions explore the outdoors.

Komoot

????‍???? Got a job listing to share? Here’s how.

???? Don’t tell Satya Nadella..

Fake Windows 11 in Svelte — This is a cute little side project, and the code is available too. The most common complaint I’ve seen is that it’s actually more responsive than the real Windows.. ???? Be sure to check out both ‘VS Code’ and ‘Microsoft Edge’ in this environment.

Yashash Pugalia

???? Prefer Windows XP? Maybe RebornXP is more for you. Complete with the classic starting up sound!

Flatlogic Admin Templates banner

All about Web API Versioning in ASP.NET Core

Introduction

Before releasing an API, we should consider how to release future improvements and possible breaking changes. For example, it is most likely that something would have to change in our APIs, such as the business requirements, resources and their relationships, third-party APIs, etc.

In general, versioning is the process of assigning a unique version (based on a specific format) per software release. The most widely used versioning format is the Semantic versioning (also known as SemVer) which is defined as follows: X.Y.Z (Major.Minor.Patch).

Major: A version for incompatible API changes.
Minor: A version for adding backward compatible functionalities.
Patch: A version for making backward compatible bug fixes.

Providing versioning in Web APIs (i.e., services) is more complex in compassion to API libraries (e.g., NuGet libraries). That is because multiple implementations (and versions) of the Web API (including their dependencies, e.g., third-party systems, databases, etc.) should be maintained and be available to the consumers. The consumers can request a specific API version by defining the version in the URI, query-string, HTTP header, or media type.

As we can understand, serving and maintaining multiple implementations of the Minor and Patch versions are not practical for Web APIs because they are backward compatible (assuming we are using the Semantic versioning). Supporting and maintaining multiple implementations of the Major versions of our APIs is a way to control how old consumers coexist with new ones.

The advice of Roy Thomas Fielding (creator or the REST architectural style on how to approach versioning in Web APIs is “Don’t” (Fielding R.T., 2013). In a very interesting interview (Fielding R.T., 2014), he provides additional information about versioning and HATEOAS in Web APIs.

From my point of view, the main question to recognize the need for versioning (Major) in a Web API is if the old consumers can coexist with the new ones. In such a case, we can provide major versioning not to break or replace already deployed components. However, we should decide carefully how many versions we will serve and maintain and how we will deprecate them. So, we will need a versioning plan 🙂.

Note: The main question to recognize the need for Major Versioning in an API is if the old consumers can coexist with the new ones.

In in-house software, where we have control over the consumers and servers (on the code and release process), we might decide not to use major versioning in our API. That is not something terrible. For example, when our consumers are internal Web APIs that we can release together or a small downtime is acceptable.

However, even in in-house software, we should consider the Single Page Applications (SPAs) cases in which different released versions can coexist on the consumer browsers. Based on our project, we should decide if it’s possible to force a refresh on the user’s web page or let the users decide when to trigger it.

Tip: In the case of SPAs, different released versions can coexist on the consumers.

In this article, we will learn the most commonly used versioning mechanisms and how we can apply them in our Web APIs by using .NET Core. Furthermore, we will see two strategies to organize our controller actions and code files. Finally, we will use Postman to perform API requests for the examined versioning mechanisms.

Versioning Mechanisms

The following table shows several versioning mechanisms that we can use to provide versioning in our Web APIs. It is important to note that the decision of the versioning mechanism influences the use of client caching and HATEOAS.

Version Mechanisms
Description
Example
Client Caching Friendly

New Route Versioning
An easy to implement but difficult to maintain solution in both consumers (clients) and server code.

From: https://api.mydomain.tld/products/
To: https://api.mydomain.tld/productsv2/
Yes

URI Versioning
The most commonly used versioning, in which we can add a version (e.g., number) to the API base URL.
https://api.mydomain.tld/v2/products/
Yes

Query String Versioning
The version is provided by using a query string parameter, such as “api-version”.
https://api.mydomain.tld/products/?api-version=2
Yes (in most cases)

Custom Header Versioning
Α custom header to indicate the version (e.g., API-Version, Accept-Version, etc.).

GET https://api.mydomain.tld/products
Accept-Version: 2
No

Media Type Versioning
The Accept header is used to indicate the version.

GET https://api.mydomain.tld/products
Accept: application/json;api-version=2.0
No

Apply Versioning at Existing ASP.NET Core Web API Project

ASP.NET Core provides all the tools that we need to apply all the mentioned versioning mechanisms. Let’s assume that we are would like to apply versioning to an existing project. So, the current API calls should work whether we specify a version or not.

Step 1: Install the Versioning Package Reference

We should install the Microsoft.AspNetCore.Mvc.Versioning package reference either by using the NuGet Package Manager in Visual Studio or using the .NET CLI (check more options here). To install it using the NuGet Package Manager (Figure 1), follow the steps:

Right-click on your Web API project and then click on “Manage NuGet Packages…”.
Search with the term “Microsoft.AspNetCore.Mvc.Versioning”.
Click on the Install button.
Click OK to the Preview Changes window and Accept the License.

Figure 1. – How to install the “Microsoft.AspNetCore.Mvc.Versioning” package.

Step 2: Configure the Versioning Services

To configure the API versioning properties of our project, such as return headers, version format, etc. I would recommend creating an extension method, such as the following. In this way, we would keep our Startup.cs (or Program.cs in .NET 6.0) file cleaner and readable.

public static class ConfigureApiVersioning
{
/// <summary>

/// Configure the API versioning properties of the project, such as return headers, version format, etc.

/// </summary>

/// <param name=”services”></param>

public static void AddApiVersioningConfigured(this IServiceCollection services)
{
services.AddApiVersioning(options =>
{
// ReportApiVersions will return the “api-supported-versions” and “api-deprecated-versions” headers.

options.ReportApiVersions = true;

// Set a default version when it’s not provided,

// e.g., for backward compatibility when applying versioning on existing APIs

options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);

// Combine (or not) API Versioning Mechanisms:

options.ApiVersionReader = ApiVersionReader.Combine(
// The Default versioning mechanism which reads the API version from the “api-version” Query String paramater.

new QueryStringApiVersionReader(“api-version”),
// Use the following, if you would like to specify the version as a custom HTTP Header.

new HeaderApiVersionReader(“Accept-Version”),
// Use the following, if you would like to specify the version as a Media Type Header.

new MediaTypeApiVersionReader(“api-version”)
);
});

// Here, we will add another service, e.g., to support versioning on our documentation.

}
}

Tip: Creating custom extension methods to add services to the container will keep our Startup.cs (or Program.cs in .NET 6.0) file cleaner and readable

In this example extension method, we perform all the configurations regarding versioning based on our needs. So, in this example, we:

Enable the ReportApiVersions to let .NET return lists of our API’s supported and deprecated versions as HTTP headers (api-supported-versions and api-deprecated-versions, respectively). In this way, our API consumers can be informed by the API for any change in versions.

Set a default API version when the consumers do not provide it (e.g., v1.0). In our case, we are assuming that we are applying versioning to an existing project. Thus, our API should be backward compatible for the consumers that do not define the version.

Read the version from multiple sources, such as query string, custom HTTP header, and Media Type header. However, we could select only one or none of them. Moreover, reading the version from our API base URL (URI Versioning) is not configured here. Thus, we could remove this part of the code if we would like to support only the URI Versioning.

Step 3: Register the Versioning Services

In this step, we should register the API versioning services in the Startup.cs or Program.cs file depending on the used style (current or .NET 6.0). That’s an easy task because of our extension method. Just add the services.AddApiVersioningConfigured(); line in the ConfigureServices method, as shown below.

// Startup.cs file in the current style

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();

services.AddApiVersioningConfigured();
}

// Program.cs file in .NET 6.0 new style

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddApiVersioningConfigured();

Step 4: Apply Versioning

Applying versioning either to an existing or new project is relatively the same. In both cases, we will have to define the API version(s) of the controller by using the ApiVersion attribute (e.g., [ApiVersion(“1.0”)]). Depending on our chosen versioning mechanism, the main difference is the route or routes that we would specify.

In the following code example, we are specifying two routes on the controller.

[Route(“api/v{version:apiVersion}/[controller]”)]: This route is specified to support URI Versioning on new or existing controllers, such as:

api/v1/weatherforecast
api/v1.0/weatherforecast
api/v2.0/weatherforecast

[Route(“api/[controller]”)]: This route could be used in an existing implementation, in which we would like to support versioning (e.g., Query string and HTTP header versioning) or just used for backward compatibility.

// List of available and deprecated Versions for this ApiController. [ApiVersion(“1.0”)]

// Specify the base (or current) API route to:

// – Keep the existing route serving a default version (backward compatible).

// – Support query string and HTTP header versioning.

[Route(“api/[controller]“)]

// Specify the route to support URI Versioning. URI example: api/v1/weatherforecast

[Route(“api/v{version:apiVersion}/[controller]“)]
public class WeatherForecastController : ControllerBase
{
// Our controller’s code…

}

Strategies to Organize Controllers and Actions

So, we have decided to support and maintain multiple implementations of the Major versions of our API. First, however, we could organize our controller actions and code files, either by the version or in the controller. You can find the following examples in GitHub.

Organize Controllers by Version

In this strategy, we group the files related to each version, such as Controllers, Data Transfer Objects (DTOs), Extensions, etc. For example, in Figure 2, we see how we could organize the files per version. We can observe that each controller uses the DTOs of its version, which can be entirely different (Figure 3).

As we can understand, the drawback of this strategy is that if only a small part of the project has Major changes (i.e., not backward compatible), it will result in a lot of duplicate code. So, we can use this strategy when we are not releasing Major changes very often.

Figure 2. – Example of organizing controllers by version.

Figure 3. – Example of different DTOs per version.

Organize Versioning in the Controller

When we organize the versioning in the controller, all different versions of the same functionality (action) are in the same controller. In this case, we use the ApiVersion attribute multiple times in the controller to list the available and deprecated versions. Furthermore, the MapToApiVersion attribute is used per action to map the API version with the specific implementation. In Figure 4, we can see how we can organize the versioning in the controller.

As we can see, if an action doesn’t have breaking changes, we can map it to multiple versions. For the sake of the example, let’s assume that the GetById should return the WeatherFoecast class. Thus, this strategy has the flexibility to perform Major changes only for some parts of the project. However, it may lead to complex code and, thus, difficult to maintain, e.g., when multiple versions exist, removing deprecated code, sharing the same DTOs, etc.

Figure 4. – Example of organizing the versioning in the controller.

API Requests with Versioning: Postman Examples

This section demonstrates how we can perform API requests for each versioning mechanism by using Postman. The presented code examples, which use the mentioned versioning mechanisms, can be found in GitHub. In addition, you can download the Postman collection for the given examples from here.

Supported and Deprecated Versions Headers

Figure 5. – Postman Example of supported and deprecated versions headers.

URI Versioning

Figure 6. – Postman Example of URI Versioning.

Query String Versioning

Figure 7. – Postman Example of Query String Versioning.

Custom Header Versioning

Figure 8. – Postman Example of Custom Header Versioning.

Media Type Versioning

Figure 9. – Postman Example of Media Type Versioning.

Summary

Versioning is the acceptance that improvements and breaking changes will occur in our project. For that reason, we are assigning a unique version per software release (usually based on the Semantic versioning format: Major.Minor.Patch).

When we release Major (breaking) changes in Web APIs, the current consumers (clients) could coexist with the new ones. In that case, we should decide carefully how many versions we will serve and maintain and how we will deprecate them. So, we will need a versioning plan 🙂.

The most commonly used versioning mechanisms use the URI, Query String, Custom Header, and Media Type. It is important to notice that the decision of the versioning mechanism influence the use of client caching and HATEOAS. Finally, we saw how the examined versioning mechanisms can be applied using .NET Core and how we can perform API requests using Postman.

Furthermore, we saw two strategies to organize our controller actions and code files, either by the version or in the controller. If we are not sure which strategy is appropriate for our project, we could start by organizing our controller actions and code in the controller (e.g., for V1). Then, we can decide when the “V2” requirements are available.

References

Fielding R.T. (2013). EVOLVE Conference 2013 Presentation. https://www.slideshare.net/evolve_conference/201308-fielding-evolve/31

Fielding R.T. (2014, December 17). Roy Fielding on Versioning, Hypermedia, and REST. https://www.infoq.com/articles/roy-fielding-on-versioning/

Manual rewrite vs automated migration: a case study

This is a tale of two projects: one which never was, and one which never should have been.

One of the great pleasures of life is meeting interesting people, and happily my job lets me do that–not as often as I’d like, but still from time to time I get the chance to spend time with customers and I always appreciate hearing their experiences and thoughts.

One of these customers who has been a real delight to know is Steven Heard, the CTO of King County (WA). We’ve done several projects for King County IT over the past few years, and had some great conversations with Steve–usually accompanied by a cold IPA or two.

Most recently, Steve gracefully agreed to participate as guest speaker in a webinar we put on in conjunction with Microsoft for state and local government IT folks. Microsoft has been interested in our automated code migration tools and wanted to showcase them for some of their customers who had older client-server applications that were blocked from running on Azure as true first-class applications (i.e. web native, not virtualized). 

We recorded the webinar, which you can watch here. I think the highlight was a case study that Steve recounted, the gist of which I want to share. If you want to jump right to the discussion in the video, it starts about 37 minutes in.

The King County Vanpool Information System

King County, Washington, is the 12th largest county (by population) in the United States and includes the cities of Seattle, Bellevue, and Redmond among others. Amazon, Starbucks, Microsoft, Costco are all here as is Boeing, although the latter moved their HQ to Chicago in a moment of municipal treachery some years ago. Traffic is a perennial problem and to help King County has one of the largest transit systems in the country including the largest vanpool system. The county “gives” you a van to use as long as you carpool people in it to your place of work. They have about 1800 vans in use and roughly 10k participants. One of my neighbors has one (a van) for her long commute from the foothills to Fred Hutchinson on South Lake Union. 

The original application to manage the vanpool system was written in VB6 and used an Access database back end (sound familiar?). That was then and this is now and who wants to work on VB6? So this app–which provides critical business value keeping the system running–was marked for modernization. 

Modernizing the Vanpool Information System (VIS)

The team that owned the app elected to rewrite it to move the technology stack to a modern platform and language, keeping the existing system functionality in order to control the scope of the project. The alternative (the project that never was) would have been to have us (Mobilize.Net) migrate the app to ASP.NET Core using Angular as the web client framework with WebMAP. We had done these projects before for KCIT so they knew we could deliver on time; we also had agreed to a fixed fee for the migration so the budget was also locked down. Steve recommended that the VIS system project get assigned to us rather than being rewritten.

But in this particular case the application owners felt they could do better rewriting internally. To clarify, the IT side of King County is de-centralized, so individual business areas own their own IT. The CTO’s role (Steve’s that is) is strategic, guidance, best practices, and so forth. My understanding is he can encourage but he can’t really force people to do things a certain way. (I might have that wrong however.)

How it started, how it went

So what happened? Before we get into the results, let’s be clear there’s no intent to criticize or blame anyone for what happened. This isn’t a case of “mistakes were made.” This is instead a case of “this is how software development (usually) works and so it should be avoided if possible.” 

Let me repeat that: you should avoid writing new software

Most software projects fail in some regard: they miss the schedule, overrun the budget, fail to satisfy the users, or some combination of the above. Five minutes on Google will provide endless horror stories of software projects gone horribly wrong, occasionally taking the organization down with them. 

Ok, to get back to our story, the original estimate for rewriting VIS was about 18 months and $325k. This was 40k lines of VB6 code (the DB had previously been moved to SQL Server) and the plan was to recreate it as a web native application. 

Shortly after project start, it was obvious the estimates were wildly optimistic, so it was re-estimated at 30 months and $550k. The second estimate was so far off the original that the project was paused for about six months while the team reviewed status and tried to build a correct and trustworthy estimate. Final experience documented was 42 months from inception and almost $750k in direct costs (total costs estimated to be closer to $800k). 

So to reiterate, it took 3.5 years and over $750,000 to deliver the same basic functionality as the original VB6 application. That 3.5 years the development team spent on this project was 3.5 years that they were not adding value to more important applications. 

The alternate scenario

The alternative approach (that CTO Steve had recommended) was to use automated migration software to reduce the time and cost of the project. Based on prior successful project experiences with Mobilize.Net, Steve estimated that the migration could have cost just under $250k and been completed in 18 months (the original time estimate for the custom rewrite).

Why? Why did one approach take so long, cost so much and the other wouldn’t/doesn’t? 

The reasons are many, but two rise to the forefront:

Estimating custom software development is really really hard. In spite of years–decades really–of improvement and innovation in software engineering process and practices, statistically as an industry we remain pathetically bad at hitting schedules and dates. And one of the root causes is scope creep. 
Automated migration eliminates scope creep. The very process is designed to produce a like-for-like translation of a legacy application into a new one that is functionally and visually equivalent if not identical to the source application. Want new features? Make changes after the migration is finished and the new application is in production. That right there locks down schedules and budgets 90+ percent of the time. By the way, that doesn’t mean the source application can’t evolve during the migration project; there are methods to merge changes into the migrated code base. But it does mean you’re not inventing new things while trying to update the old stuff at the same time. 
But don’t take my word for it,
you can watch the webinar here. Enjoy!

How to Start Your Own Blogging Journey

Introduction

One year has passed since the publication of the first article in the .NET Nakama blog. Happy birthday .NET Nakama 😀.

Figure 1. – Happy birthday .NET Nakama.

This blog has started from my need to help other developers improve their .NET skills. So, I decided to share my learning journey, teaching materials, thoughts, ideas, and source code. Along the way, I am also improving my skills and meeting new people. It’s a great experience so far, and I hope to keep blogging about .NET and be a .NET Nakama for you.

You may be thinking about what Nakama means. Nakama (仲間) is a Japanese word that translates to a friend, buddy, circle of friends, etc. Under some context, such as in the One Piece manga and anime, it translates to crewmates. So, regarding .NET Nakama, I am thinking of it as a place where .NET developers can share ideas, learn and improve, as they would talk to a friend about .NET.

In this anniversary article, I will share my experiences as a blogger (so far) and what helped me when starting this blog. But, of course, I am still learning, and there is a large room for improvement.

How to Start

I was thinking of starting a blog about .NET for a long time but not actually starting it. I needed a small “push” and some help to get started. The next list shows what you could do to start your own blog.

Select a blog topic depending on what you would like to write about.
Do not overthink if a topic is too simple or not. Even simple articles (for you) would give value to someone.
Your first articles can be for “something” that you feel more comfortable with (easier to write about).
Improvements to your writing style or your blog, in general, can be made with time.
Before publishing an article, you can give it to someone close to you (a friend, partner, etc.) to proofread it. In this way, you will be more confident and with no spelling and punctuation mistakes, typos, formatting issues, and inconsistencies.
With time, you will improve your writing skills and feel more comfortable writing more complex articles.
You can get some help to start blogging and for your next steps. There are numerous articles on the web about this topic. For me, John Sonmez’s (Simple Programmer) email course and workbook were a big help to start blogging, especially because:

I found answers to all of my questions, e.g., how to select my blog topic (theme).
I learned about the basic way of thinking when building a blog (consistency, not good enough syndrome, etc.).
It provided me the impetus to take the first step.
From time to time, I am reading the email course again and always find something useful.

What It Requires

To maintain a blog requires several things. The main requirements are time, consistency, and patience.

Time and Effort

Depending on the number and size of the articles you will publish.
Depending on the time you can spend.
Do not underestimate the time and effort it takes for an article to be written.
You will have to decide how many articles you can publish per month.

Consistency

Be consistent with the blog topic.
Stick to the decided number of articles per month. For me, it’s one article per month.
Publish articles consistently.

Plan Ahead

Create a list of future articles.
Pre-write content and keep comments and ideas for your next articles.
Always have one article ahead ready. In this way, you will be more flexible when something unexpected happens.

Patience

Do not expect your blog to become popular (but it can happen).
You do not need to implement every cool feature from the beginning. You will have the time to introduce new features to your blog.

Prepare Yourself

You have to be prepared, understand why you want a blog, and set goals.

Think about why to bother sharing your ideas and work.
You will definitely receive negative reviews!

That’s good! Someone took the time to read your article and answer you.
If it is constructive criticism, it can help you to improve.
Try to see what you can learn from the review (regardless if it’s good or bad).

Do it for yourself, so you will feel better by offering and helping others.

Tools & Services

The most popular tool to create a blog is WordPress, which is scalable, newbie-friendly, and with many features.
For my needs (small number of articles and authors), I have selected Jekyll, a static website generator. Alternatively, you can investigate Hugo. Static website generators:

Are easier to be hosted (without the need for a database) in simple and cheaper hosting plans (sometimes provided for free).
Are easier to perform CI/CD.
Have Increased Performance (the HTML files are already rendered).

I have used the Long Haul template. I am sure that you will find a template that you would like.
For Domain Name System (DNS) and Content Delivery Network (CDN), I am using Cloudflare.
I am using the Visual Studio Code as a code editor for the blog, which is extensible, customizable, and cross-platform.
For the .NET Code examples, I am using the Visual Studio IDE (currently the 2019 Community).

Summary

Happy birthday .NET Nakama 😃. In this anniversary article, I shared my experiences as a blogger (so far), what helped me start this blog, and what tools I am using. Of course, I am still learning, and there is a large room for improvement.

If you are thinking of making the first step to start a blog, do not hesitate! Learn from others and accept help. For me, John Sonmez’s (Simple Programmer) email course and workbook were a big help to start blogging. If you have any questions, feel free to contact me 🙂.

Thank you for reading and sharing my articles, sending suggestions and feedback, and contributing to my open-source projects.