Scott Hanselman

SharpScript from ServiceStack lets you run .NET apps directly from a GitHub Gist!

August 16, 2019 Comment on this post [10] Posted in DotNetCore | Open Source
Sponsored By

I've blogged about ServiceStack before. It's an extraordinary open source project - an ecosystem of its own even - that is designed to be an alternative to the WCF, ASP.NET MVC, and ASP.NET Web API frameworks. I enjoy it so much I even helped write its tagline "Thoughtfully architected, obscenely fast, thoroughly enjoyable web services for all"

ServiceStack is an easy drop-in that simplifies creating Web Services in any ASP.NET Web App, but also in Self Hosting Console Apps, Windows Services and even Windows and OSX Desktop Apps - supporting both .NET Framework and .NET Core. The easiest way to get started is to create a new project from a ServiceStack VS.NET Template.

ServiceStack has released a new and amazing project that is absolutely audacious in its scope and elegant in its integration with the open source .NET Core ecosystem - #Script (pronounced "sharp script.")

Scripts IN your app!

There are a number of .NET projects that simulate REPL's or allow basic scripting, like "dotnet script" as an example or ScriptCS but I'm deeply impressed with #Script. To start with, #Script is somewhat better suited for scripting than Razor and it doesn't require precompilation. #Script is appropriate for live documents or Email Templates for example.

Here's a basic example of embedding a ScriptContext in your app:

var context = new ScriptContext().Init();
var output = context.EvaluateScript("Time is now: {{ now | dateFormat('HH:mm:ss') }}");

Where ServiceStack's #Script really shines is its use of .NET Core Global Tools. They've nabbed two global tool names - web and app (sassy!) and allow one to create SharpApps. From their site:

Sharp Apps leverages #Script to develop entire content-rich, data-driven websites without needing to write any C#, compile projects or manually refresh pages - resulting in the easiest and fastest way to develop Web Apps in .NET!

The web tool is cross platform and the app global tool is great for Windows as it supports .NET Core Windows Desktop Apps.

Your app IS a script!

You can write interactive SharpScripts or SharpApps that uses Chromium as a host.

You can literally run a "desktop" app self contained from a GitHub Gist!

Sharp Apps can also be published to Gists where they can be run on-the-fly without installation, they're always up-to-date, have tiny footprints are fast to download and launch that can also run locally, off-line and cross-platform across Windows, macOS and Linux OS's.

There's also a "gallery" that maps short names to existing examples. So run "app open" to get a list, then "app open name" to run one. You can just "app open blog" and you're running a quick local blog.

SharpApps

Easy to develop and run

The global tools make SharpApp a complete dev and runtime experience because you can just run "app" in the source folder and as you make code changes the hot-reloader updates the site as you Ctrl-S (save) a file!

If you've got .NET Core SDK installed (it's super quick) then just grab the local tool here (app on Windows and web anywhere else):

dotnet tool install --global app

And if you have a existing .NET Core web app you can launch it and run it in a Chromium Embedded Framework (CEF) browser with "app foo.dll" Check out this example on how to make and run a .NET Core app on the Windows Desktop with #Script.

ServiceStack CEF App

Then you can make a shortcut and add it to to the desktop with

app shortcut Acme.dll

Slick!

Code in #Script is done in markdown ```code blocks, while in Razor it's @{ } but it does use mustache template style. Go try out some of their Starter Projects!

#Script and SharpApps is an extraordinary addition to the .NET Core ecosystem and I'm just touching the surface. Do check out their site at https://sharpscript.net.

What do you think?


Sponsor: Develop Xamarin applications without difficulty with the latest JetBrains Rider: Xcode integration, JetBrains Xamarin SDK, and manage the required SDKs for Android development, all right from the IDE. Get it today!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
August 21, 2019 14:32
Bu there is already a Script# language. That will get confusing )
August 21, 2019 15:28
What are the licensing implications/usage restrictions/long term support implications of using this?

ServiceStack is commercial as I recall.
August 21, 2019 15:34
@Harry #Script can be used for free without restriction, I've answered questions about its free usage and licensing on the HN thread: https://news.ycombinator.com/item?id=20755929
August 22, 2019 0:18
WOW this is awesome!
August 22, 2019 1:38
I prefer the ClearScript project much more than this, for the simple reason it runs JavaScript, and not a custom language.

This one is a nice idea, with lots of great features, but it comes to the language, this is crucial to define adoption in an ecosystem. Going the JS path is much more appealing to the dev public, since they can reutilize their existing skills.
August 22, 2019 1:42
Just complementing, it would be great if MS or the community would apply the same ideas of SharpScript into ClearScript.
August 22, 2019 3:51
#Script is modelled after JavaScript and supports JavaScript expressions including support for some JS Objects like JavaScript Arrays.

It adds additional features which make it more suitable for usage in templates, e.g. it adopts Handlebars block helpers syntax for its script blocks which is an important feature to be able to easily generate dynamic markup like dynamic HTML since it represents a majority of its use-cases.

The pipe operator allows for more readable code as found in Vue.js Filters and Angular Template expressions.

#Script is also highly extensible where there aren't keywords baked into the language per-se, all functionality is added via script methods and script blocks, e.g. the `to =>` assignment is just calling the `to` C# script method and all methods and blocks can be easily removed, shadowed or replaced to create your DSL language. The ability to run in a controlled sandbox that can define all functionality available to #Script's is also an important property to be able to allow safe execution from untrusted sources as well as elevated access to Protected APIs in safe contexts.
August 22, 2019 10:51
@Johann @Demis Bellot

I don't get the comment about using JS?

This all seems to be about running C# in a script like fashion which is not the same as running JS - which is already a script language.
August 22, 2019 12:30
@Peter

Right, they allow scripting in .NET Apps. The usage of JavaScript is for familiarity and because it's also better suited as a dynamic scripting language. But JavaScript isn't ideal as a template language so #Script also adopted Handlebars syntax for its statement blocks.

The pipe operator is also popular in templating languages (e.g. Angular Templates/Vue Filters) because it's much more readable and wrist-friendly to transform values with a pipe chain:

{{ a | b | c }} then to use method invocations {{ c(b(a())) }}

So #Script is essentially = JS Expressions + Handlebars blocks + Pipe operator

It does add some of its own convenience syntax like its short-hand lambda syntax where you can use an implicit `it` param (from Kotlin) for single param lambda expressions, e.g:

{{ [0,1,2,3,4,5] | where => it < 3 | map => it + 10 | join }}


as an alternative to specifying explicit formal parameters for each lambda:

{{ [0,1,2,3,4,5] | where(it => it < 3) | map(it => it + 10) | join }}


Allowing all script methods being called as extension methods also adds to readability, so install of calling method with their normal positional arguments:

itemsOf(3, padRight(reverse(arg), 8))


you can call them as an extension method when it improves readability and better expresses the codes intent:

3.itemsOf(arg.reverse().padRight(8))


and #Script's code feature is common in template languages to switch from "template" mode to "code", e.g:


Razor:
@{
var a = 1;
var b = 2;
}
Basic Calc
a + b = @(a + b)



#Script:
```code
1 | to => a
2 | to => b
```
Basic Calc
a + b = {{a + b}}


Which is useful in code-only scripts like Shell Scripts and Live Documents as popularized by Literate programming, which I'd love to see more of.
August 27, 2019 16:46
Hi, please check this offer, there are many nice things that I know you will love
[url=https://amzn.to/2Zh0moC]Look what I have found[/url]

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.