Category Archives: software development

.NET 11: unions, MAUI ready for business, but what comes next?

Microsoft has released .NET 11, as part of the online .NET Conf under way today and tomorrow. It is not a long-term support (LTS) release though that detail does not mean all that much; it will be supported for two years, and if like me you upgrade soon after each new release everything is fine.

.NET 11 is now fully released

New features include union types in C# 15, faster asynchronous code, Core CLR on all platforms in place of Mono in MAUI (Multi-platform app UI), and hundreds of other improvements across the runtime and frameworks including ASP.NET Blazor and even the venerable Windows Forms.

Personally I am most interested in the performance improvements, and in the progress of .NET MAUI which after years of troublesome issues now looks to me a strong contender for cross-platform mobile and desktop development.

I like programming in C# and for me it hits a sweet spot of safety, performance and ease of use. Microsoft’s stewardship of the language and of .NET has been good in general, though it fumbled the handover to the .NET Foundation. There is still too much dependence on one company and despite the open source and cross-platform aspect, the technology remains associated with Windows which holds back adoption.

For further background on the inadequacy of the .NET Foundation check out this report from F# Software Foundation Executive Director Reed Copsey which says “I find myself unable to honestly recommend anybody put time or effort into the Foundation, or recommend joining as a member” and that “independence of the Foundation is disingenuous” thanks to bylaws that ensure that “the .NET Foundation is prevented, by design, from being able to self-govern and impact meaningful changes without direct support of Microsoft.”

The future of .NET is in largely in Microsoft’s hands and the question is where it will go now that programming is in the process of disruption by AI, a process which is still under way and the outcome of which is uncertain. If one takes the view that coding will largely be done by AI in future then programming languages and runtimes will change accordingly. We can see a little of how Microsoft is thinking about this with the introduction of WinUI Reactor, a framework for WinUI application using C# that is designed for agents as much as for people.

If we consider though the elements of the sweet spot I mentioned above, safety, ease of use, and performance, we may conclude that ease of use is no longer important (because humans are not using the language), and that for performance we should ask AI to use a system language such as C, C++ or Rust. And of these three, Rust is a winner because safety still matters, and AI is not immune from making memory safety mistakes.

I am therefore uncertain whether we will see the established yearly cycle of major .NET releases every year repeat for much longer. Microsoft may shift more investment towards AI and Rust.

That said, Microsoft has a strong track record of maintaining technology in use by its customers and developers can be confident that .NET and its various frameworks will continue to be maintained for long into the future.

C++ in crisis following disapproval of C++ 26

A member of the WG21 C++ standardisation committee, Andreas Fertig, has asked “how does C++ survive” following the disapproval of C++ 26 by the ISO National Bodies.

C++ will survive but there is now a question mark over C++ 26, which was already approved by the standardisation committee and for which approval by the national bodies is normally a formality; Fertig said that this is the “first time in the history of C++” that it has happened.

The reason for the disapproval is a particular feature: Contracts, a means of setting preconditions and postconditions on function declarations and adding assertion statements within functions. Although the idea behind Contracts is generally welcomed, there are disagreements about the implementation. Herb Sutter, chair of WG21 is an advocate for the C++ 26 implementation, while Bjarne Stroustrup, inventor of C++, is opposed. Stroustrup said that the feature is “adding complexity in very obscure ways … I worry about the complexity, I worry about whether we can use it correctly.”

Stroustrup faces obstacles standardising a feature he champions called Profiles, which like Contracts are intended to improve the safety of C++ code. Another C++ expert, Sean Baxter, argues that “after a decade of effort, Profiles failed to produce a specification, reliable implementation or any tangible benefit for C++ safety. The cause of this failure involves a number of mistaken premises at the core of its design.” The controversy around profiles resulted in the proposal being removed from C++ 26 though still possible for C++ 29.

The question is what happens next for C++ 26, which also includes significant features such as Reflection and Annotations. Fertig said that the next steps are “more than uncertain”; the next WG21 meeting is on November 16th and will try to resolve this. If the Contracts feature is removed, a further vote on C++ 26 would probably pass; but this would require the committee to abandon a feature it strongly supports. Another possibility, according to Fertig, is that C++ 26 will be cancelled, extending the life of C++ 23 as the latest version.

It is a problem for the standardisers and also for the trust within the community. Depending on your point of view, this is an example of tyranny of the minority, or that one cannot proceed without greater consensus. Discussion here and here shows that developers in general have reservations both about the implementation of Contracts and regarding the over-complexity of the C++ standard.

WinUI Reactor: yet another way to code for the Windows desktop

Microsoft principal software developer engineer Alexandre Chohfi has posted about WinUI Reactor, an experimental framework for building WinUI applications using C# and a reactive pattern. The rationale for Reactor is two-fold:

  1. The popularity of React for web applications, and other reactive frameworks like SwiftUI and Jetpack Compose, makes using XAML for the user interface a barrier to adoption.
  2. Writing the user interface in plain C# is “easy for coding agents to read, write and check, so we now design for agents as well as people,” said Chohfi.

Note that Reactor is not a new platform, it is another way to code for WinUI, the existing platform which is supposedly the native UI framework for Windows but which competes with old-style Win32 (targeted by Windows Forms) and the DirectX-based WPF (Windows Presentation Foundation).

The easiest way to get started with Reactor is via the winapp CLI. Install the latest version and type winapp new selecting Reactor MVU App.

Creating a Reactor app with winapp.

The template coincidentally creates a counter app similar to the one in Chohfi’s post. The UI is coded in a Render method and there is no XAML file, everything is done in C#.

The Reactor demo app in Visual Studio Code.

Chohfi’s variant, which is also in the docs, is simplified but functionally the same. The template demo app calls UseReducer, whereas the documented demo calls UseState.

This may seem a terrible time to introduce a new (first previewed at Build in May) C# framework for desktop Windows. The niche for Windows desktop apps, mainly business applications, continues to shrink. Developers already face too many choices. Legacy .NET applications generally use Windows Forms or WPF, both of which still work.

It is hard to see many React developers wanting to switch to WinUI, when there are many ways to code desktop applications in JavaScript or TypeScript, including React Native, which seems a more natural choice.

Another issue is that this is not cross-platform. Coding a new application for Windows only seems short-sighted in most scenarios, hopeless for the consumer market, and for business use limited to companies standardised on Windows. That said, there is always an argument for using native frameworks on each platform, if the resources exist to build WinUI for Windows, SwiftUI for Mac and so on.

There is a Rust variant of Reactor and one can see this being of considerable interest, to Microsoft internally as well as for other developers. AI plus Rust is a potent combination.

There are indications that Microsoft is serious about Reactor, particularly in the remarks in Chohfi’s post about new Reactor controls being “candidates to land in WinUI itself,” and that “we’re actively working with the C# team” such that Reactor may influence the C# language.

I was also interested in Chohfi’s remarks about the mental model required to understand application code. For a XAML-based app, he said that “what does this screen look like when Count is 5 is a question you answer by reading three files and mentally running a binding engine. In Reactor, that last question has a very boring answer: read Render().”

I suspect that this is a reason for the continuing appeal of the Windows Forms framework. The mental model seems easy: one places controls on a canvas, sets their properties, and for interactivity one can just double-click a button and write the code that will run. This does not work so well for a complex application, but for something simple it is fine.

The MVVM (model-view-viewmodel) architecture which is common (though not required) for .NET applications has advantages, but even Microsoft architect John Gossman who was an early advocate for the pattern said that “for simple UI MVVM can be overkill” and that large numbers of bindings impact performance.

Reactor is MVU (model-view-update), as is React. In this pattern, the model is the state of the application, the view displays the state to the user, and update sends messages to update the state, triggered by user interaction or server activity.

A new era of AI-driven application rebuilds – now it is Microsoft Office and Adobe Photoshop

AI coding makes it easier and quicker to re-create existing applications with new code, side-stepping copyright concerns since copyright protects code rather than specification.

In February this year Cloudflare rebuilt Next.js with AI in one week and then followed with a WordPress-compatible CMS (content management system) called EmDash.

Brandon Thomas, a developer from Atlanta, Georgia in the USA, founded Artcraft with the goal of creating clean-room implementations of popular (and expensive) applications including Adobe Photoshop, LightRoom and InDesign; Figma; Microsoft Word, Excel and PowerPoint; AutoDesk’s AutoCAD, and more.

The applications are coded in Rust, run cross-platform on Windows, macOS, Linux and FreeBSD, and Web via WebAssembly, and are open source on GitHub under the Apache 2.0 license. The GUI is driven by the egui library, which means controls are not native but drawn by the library.

On LinkedIn, Thomas said that “we do not decompile binaries or copy Adobe Code” and “yes, I am actually an engineer.”

The ArtCraft implementations have some advantages over the commercial originals, in that they run on Linux, promise no tracking or ads or telemetry gathering, and can perform well thanks to the Rust’s efficiency.

On Hacker News Thomas said that “software is over” and that this initiative heralds a new era of escape from what he called “cellphone incrementalism and platform lock-in.”

Let us not get carried away yet. I tried WordCraft (whose name I recall from a word processor for the Commodore Pet which could only hold a few paragraphs in memory before painful paging to disk) and was both impressed and disappointed. It looks great but failed to render a complex Word document which I have used before to test LibreOffice.

WordCraft scrambled this awkward Word document

It is early days though and no doubt these and other issues will be fixed; most of the ArtCraft applications are described as Alpha releases.

Although the clean-room method is well established as a defence against copyright infringement, it does not remove patent restrictions. It is also now obvious that treating code as the essence of an application’s intellectual property is no longer possible and one must expect legal arguments if these applications, or other similar works, gain ground.

Nevertheless, the assumption that recreating applications to escape vendor lock-in is too expensive and difficult is now breaking down.; it is a big change for the industry even if, right now, it is hard to see all the implications.

JetBrains posts a loss (but revenue is up), puts spotlight on future of IDEs

A report that independent developer tools vendor JetBrains posted a financial loss for the first time in “tracked history” prompted much discussion on Hacker News, though the title of the thread was changed from one that was too negative, since the company is not in any sort of financial trouble, to one that is too positive.

Revenue is up 6.26% and at a record level so there is that; but staff expenses rose 34.2%, operating expenses rose 26.5%, and the figures are consistent with the idea that the company is attempting to find new AI-flavoured directions to support the future of software development, a challenging task since nobody knows what that is.

Perhaps most concerning for JetBrains are the many comments from developers cancelling subscriptions. “I’ve been a JetBrains subscriber for over a decade. Nobody is going to use their tools in five years. I certainly don’t need my subscription anymore,” said one.

The core issue is that AI agents do not need IDEs. “I was a big IDE user since they existed (I used Visual C++ beta releases in 1992). However, since adopting AI tools I really haven’t used an IDE. Once in a while for things I don’t know how to do without one (e.g. view a markdown file locally). That’s it though,” said another.

This view is by no means universal. As it happens I am personally using IDEs more than I have for a while, working on a project porting a Windows Forms project to modern cross-platform C# code (current MAUI though that could change). I am not using much AI for this, partly to control costs and partly because it does not seem well suited for it, though I could be wrong.

Developers empowered with AI sometimes deliver terrible code. This comment is an example:

“I have seen a bubble sort function in a PR from an engineer with 10 years of experience. Meanwhile sort from standard library is easily available with one single line … that same engineer sent out a PR of 200-file feature. The PR is so large that it freezes the latest MacBook Pro if you try to read it. Nobody reviewed it and he merged it himself. Nobody uses that feature, and nobody in the teams wants to maintain it. Now we are considering scrapping it.”

If AI is the future of software development, we have to get better at using it.

A new State of Devs report shows that developers are having a tough time. Burnout is high; 66% of respondents report “reduced motivation” and 57% are “emotionally drained.” Regarding AI, opinions are evenly divided on whether it is a net positive or negative; however there is a majority opinion that it has a negative impact on mental state and many reports that it has as many downsides as benefits. “AI has sapped the joy of the craft, shattered my focus, and every day I find myself closer to throwing in the towel and taking a year out to travel and decompress,” said one developer. There is anxiety not only about job security, but also code quality, deskilling, and pressure to deliver more features more quickly.

Finally, a comment from a JetBrains representative corrects a common misunderstanding, that the company has invested heavily in AI tools like Junie at the expense of maintaining the quality of its core IDE framework IntelliJ. “Junie is like 30-40 people (haven’t checked exactly, but the order of magnitude is correct), IntelliJ headcount is in thousands just for perspective. I don’t quite see how it can affect other products or financial health. Junie also doesn’t subsidise usage, so it is not a money burning machine either.”

Shopify migrates from React Native to native Android and iOS development, citing AI as enabler

Cross-platform development fascinates because of its many nuances. Is it more important than an app works the same on each platform, or that it is optimized for the best experience? Is it more important to share code for better maintainability, or to have separate code bases to avoid compromising? And if one does go the for a cross-platform framework, what is the best choice?

Back in 2020, Shopify decided on React Native as its solution; now it is changed its mind. The company has several mobile apps, including one called Shopify aimed at vendors using its service, and another called Shop aimed at consumers. Shop has a five-star rating and is the 7th most popular shopping app in the iOS App Store.

When it adopted React Native after “years of native mobile development”, the company cited three reasons: acquisition of another company with deep React Native skills (Tictail); harmony with its use of React in its web applications; and the improving performance of the React Native framework. Shopify said that an early rewrite of Shop (formerly called Arrive) had less crashes on iOS than the native version, and shared 95% of code with the Android version.

Now, Shopify engineers say that “advances in coding agents changed the tradeoffs behind maintaining a shared mobile codebase.” The native port of Shop, now using Swift on iOS and Kotlin on Android, has a faster start-up (23% improvement on iOS, 50% on Android), improved stability, and on Android, 37% smaller release build size.

React Native has a new architecture with many improvements; however migration to this has challenges and avoiding this work for its Shop app was another factor in Shopify’s decision – though it had already migrated two other apps. This also means that Shopify’s comparisons are with the old React Native architecture; one might speculate that migrating to the new architecture would also have brought benefits. That said, its report on migrating the other apps (Shopify Mobile and Shopify Point of Sale) was mixed; start-up time slightly improved, but the team discovered performance and stability issues which required work. “These were not to blame on the New Architecture itself. It just revealed cracks in some component designs that were previously invisible,” said Shopify at the time.

The key point of interest is not so much the change of mind but the role of AI coding in the decision. The company said that “Native still means building and maintaining software on two platforms, that cost has not disappeared. What changed is that agents can now do enough of the implementation, translation, testing, and review work that it’s no longer the deciding factor it was in 2020.”

What works for Shopify may not work so well elsewhere. Personally I am nervous about AI coding for several reasons, including cost, security and subtle bugs. As an individual developer, the notion of paying continually for software development is unattractive; that does not apply to a larger company which asks only whether the benefits exceed the costs.

First steps with MAUI: some friction

I am evaluating Microsoft’s MAUI (Multi-platform app UI) for use on a cross-platform project. I mainly develop on a Mac with Visual Studio Code.

Setup for MAUI development is well explained here though getting everything in place for Mac Catalyst, iOS and Android is tedious. There is a tricky issue related to Apple’s Xcode, needed for MAUI for the Apple targets. Apple’s recommendation is that you install Xcode from the App Store. As you would expect, it updates quite frequently and always when there is a new version of macOS. The version on my machine is therefore 26.6. After installing MAUI for .NET 10 I got an error when trying to build, stating that I had the wrong version (mine was too new).

The workaround for this is either to install multiple versions of Xcode, which is fiddly, or to set ValidateXcodeVersion to false in the .csproj project file.

As it turns out, there is another fix. The .NET for iOS SDK (used by MAUI) was updated last month to require Xcode 26.6. Note: require, not support. Each version of the SDK requires one and only one version of Xcode, and there is a lag between Apple releasing a new version, and Microsoft updating its SDKs.

My instinct is to set ValidateXcodeVersion false during development and to watch out for strange errors that might be fixed for a production build, using the correct Xcode version.

Microsoft’s MAUI SDK engineering lead said:

Updates can include different things that amount to varying levels of work. Sometimes there’s api changes in the SDKs Xcode ships that we need to account for, sometimes they change Cli tools or break things in other ways. Depending on the changes it can be a little bit of work or a lot. 

Lately minor version updates to Xcode tend to be somewhat compatible with existing MAUI (Mac/ios) workloads and you can technically force trying to use it with the right build settings, but we generally advise not installing Xcode from the App Store so that it isn’t silently updated and you can install updates when you know they’ll be supported by MAUI instead.

This is friction, though it comes with the cross-platform territory. Note that Apple insists on building with the latest Xcode for store submission.

With that out of the say, I started building an experimental app. This is not Windows and conceptually one should think of the app UI as a single page, mobile app style, even if developing for Windows and Mac Catalyst. I decided to use a Tab Bar for navigation, but ran into an issue: when debugging the app for Mac Catalyst, the Tab Bar did not appear.

I thought this was something I was doing wrong, even though it was a simple and basic case. Then after digging a bit I discovered that it was a bug, that I was not the first to hit it, and that it was fixed with a workaround late last year.

The solution is to run: dotnet workload update from the command line to get the latest version.

Both issues are a reminder of how tricksy cross-platform development can be, particularly for frameworks like MAUI which use native widgets rather then drawing them from scratch like Flutter or Avalonia UI.

The solution, it seems to me, is to keep the user interface simple.

Vercel’s Scriptc is a TypeScript to native code compiler – how did we get here?

Vercel has previewed Scriptc on GitHub, a native compiler for TypeScript which is open source under the Apache 2 license.

Scriptc takes TypeScript code as input and outputs a native code executable, along with an embedded JavaScript engine if needed, using the existing QuickJS ng project. The JavaScript engine is needed if there is code included that cannot be statically compiled, including JavaScript code, such as npm dependencies, or code typed as “any” in TypeScript.

Scriptc runs on Apple Silicon and uses cross-compilation to target Linux and Windows. The project claims some big improvements in performance: startup time for an example workload reduced from 47ms to 2.4ms, memory usage down from around 100MB to 4MB, binary size reduced from around 80MB to 3MB.

How Scriptc compiles TypeScript to native code

The Node.js API is supported as well as the TypeScript language and the idea seems to be that server applications running on Node could be compiled to native using this tool.

Although this sounds promising, comments on Hacker News are not entirely favourable. “The architecture is idiotic, they have zero credible perf numbers,” said one, claiming that the “project reeks of weapons grade AI psychosis.” Expanding on this, complaints include the use of QuickJS, using floats for numbers, and resorting too quickly to an embedded JavaScript engine.

Vercel as a company is enthusiastic about AI and Scriptc appears to have been made largely with AI.

When Microsoft introduced a native code TypeScript to JavaScript compiler in TypeScript 7, greatly reducing compilation time, the awkward question was: if native code is so much faster than JavaScript, why not use a more performant language for the application code as well?

How did we get here? It all started with Brendan Eich’s LiveScript for Netscape Navigator, renamed JavaScript when first released in December 1995, and the beginning of interactive web pages. Part of the thinking behind JavaScript was that it could be used to script Java applets – Java components embedded in web pages – but JavaScript itself was always more popular. Adobe used a variant of JavaScript, called ActionScript, for its Flash add-in which at one time looked likely to dominate the web.

Using the web browser as an application runtime was critical for companies trying to bypass Microsoft’s desktop application dominance, and Google in particular invested in JavaScript, creating the V8 JavaScript engine for its Chrome browser, first released in 2008.

Then came Node.js, a server-side runtime for JavaScript based on V8 and first released in 2009 by Ryan Dahl. Dahl was particularly interested in improving concurrency in web applications, but another thing that drove adoption was that developers could use the same language both on the server and in the browser, and that JavaScript was an easy language to learn.

The mass adoption of JavaScript that followed also exposed its shortcomings. Microsoft’s Anders Hejlsberg, who also invented the C# language, believed that strong typing for JavaScript was essential in order to make large applications maintainable. He therefore came up with TypeScript, a superset of JavaScript with strong types that compiles to JavaScript for runtime compatibility.

TypeScript has proved wildly popular and most applications which target JavaScript are now written in TypeScript. If we add Scriptc or an equivalent into the mix, then the JavaScript element is all-but eliminated, though note that as currently designed Scriptc will run some of the code in a JavaScript engine so we are not there yet.

If you write in TypeScript and compile to native code though, why use TypeScript, why not use Go or Rust? Or if those languages are too demanding, Java or C# both of which have strong ecosystems?

The answer is the familiarity of TypeScript, the massive range of npm packages, and the ability to use the same language on the server and in the browser.

Nevertheless, the problem which Scriptc sets out to solve can perhaps be bettered simply by choosing a more performant application stack and reserving TypeScript for code that runs in the browser.

Getting started with Azure Artifact Signing

Signing applications is a requirement for deploying a desktop or mobile application and can be fiddly. Microsoft’s Azure Artifact Signing always looked to me like a good solution in that the pricing is reasonable at $9.99 per month for up to 5,000 signings, and it is run by Microsoft so one would think that the certificates will be satisfactory for Windows users.

This week I got started with the service. Microsoft has a handy quickstart guide and the first thing to note is that availability is limited to USA and Canada for individual developers, or USA, Canada, EU and UK for organizations. Luckily I work for a small UK limited company so qualify as an organization.

I also noted that a pay as you go Azure subscription is required; if you have a sponsored subscription that will not work.

The first step is to create an Artifact Signing Account. Billing starts from when this account is created, even if you are unsuccessful in obtaining a signing certificate. Should this be the case, make sure to delete the account.

Next, check the roles assigned to the user that will operate the code signing. There are two: Artifact Signing Identity Verifier and Artifact Signing Certificate Profile Signer. I assigned them both to my Entra ID user.

Now there are two steps to obtaining a certificate profile. The first is Identity Validation. In my case this is for an organization; you will need a DUNS number, two valid email addresses, a functioning web site, and the first and last name of the individual that will use the service. The organization address should match the one recorded at Companies House, even if day to day work is done elsewhere.

The organization identity verification automatically progresses to individual identity verification. In my case this was done by a company called AU10TIX and I was able to use a UK driving licence.

Next I hit what looked like a roadblock. I received an email asking me to verify my email address; however clicking the link got me a web page stating “the request is blocked” and “service unavailable”. Thinking that perhaps the service was unavailable, I tried several times and on different networks. I am not the first to experience this. I was on the point of raising a support case when I got a further email advising that validation was complete.

Once identity validation is complete you can create a certificate profile. The type I need is called Public Trust. I had several mysterious failures with uninformative errors; I suspect this might be to do with non-unique profile names but no idea really. Again I was on the point of contacting support when I tried a new profile name and it worked.

The quickstart guide ends at this point and the next document you need is the one on setting up signing integrations. You will need a recent Windows SDK including SignTool.exe, the .NET 8.0 runtime, and the Azure Artifact Signing client tools, if like me you want to sign a Windows executable.

Then you need to create a JSON file traditionally called metadata.json, and a command to sign the file. The command will be lengthy so fire up Notepad or similar and put it in a .cmd file or similar. You need to discover the location of SignTool and the location of Azure.CodeSigning.Dlib.dll and note that there are different x64 and x86 versions.

The command includes a timestamp without which the code signing is useless as the certificate has a lifetime of just three days.

I carefully assembled the command and I am happy to report that it worked first time.

Output from code signing command

So far so good. The whole process is somewhat intricate but I am hoping this will prove a good solution for Windows.

Kimi K3 and Qwen 3.8: is AI becoming a commodity?

Last week Moonshot AI introduced Kimi K3, with the promise that “the full model weights will be released by July 26 2026;” while Alibaba said on X that “Qwen 3.8 is launching and going open-weight soon”.

These are capable LLMs (large language models), and the open weights promise means that developers will be able to download them from Hugging Face and run them locally.

There are two reasons why local AI is inferior to pay-as-you-go cloud AI from one of the big providers: the LLMs are not as good, and the hardware is much inferior to data centres stuffed with massive amounts of RAM and GPUs.

However, there are also two reasons why local AI is much preferable to cloud AI: it is free to use, and more private. As an individual developer the notion of a constant trickle of spend while coding is disturbing, though I also see how the figures can make sense in a business context if there are corresponding benefits in productivity or staff numbers.

LM Studio using Qwen 3.6 to write some C# code

Joining the dots though, it seems possible that as local AI improves the premium (and uncertain) cost of what is sometimes called frontier AI will no longer be worth paying for.

Someone has to pay for the LLMs and there are political as well as technical aspects to this, as there are in other areas of IT. The implications of commoditised AI though are considerable, and means that we can expect further shifts in the tech landscape in this space.