diff --git a/samples/StandaloneApp/Index.cshtml b/samples/StandaloneApp/Index.cshtml
new file mode 100644
index 0000000000..f731b5af5a
--- /dev/null
+++ b/samples/StandaloneApp/Index.cshtml
@@ -0,0 +1,3 @@
+@inherits Microsoft.Blazor.Components.BlazorComponent
+
Hello, world!
+Hello from the Razor component.
diff --git a/samples/StandaloneApp/Program.cs b/samples/StandaloneApp/Program.cs
index e5000876a7..4d441d31f5 100644
--- a/samples/StandaloneApp/Program.cs
+++ b/samples/StandaloneApp/Program.cs
@@ -4,7 +4,6 @@
using Microsoft.Blazor.Browser.Rendering;
using Microsoft.Blazor.Components;
using Microsoft.Blazor.RenderTree;
-using System;
namespace StandaloneApp
{
diff --git a/src/Microsoft.Blazor/Components/BlazorComponent.cs b/src/Microsoft.Blazor/Components/BlazorComponent.cs
new file mode 100644
index 0000000000..b8cf2b560f
--- /dev/null
+++ b/src/Microsoft.Blazor/Components/BlazorComponent.cs
@@ -0,0 +1,38 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.Blazor.RenderTree;
+using System;
+using System.Threading.Tasks;
+
+namespace Microsoft.Blazor.Components
+{
+ ///
+ /// Optional base class for Blazor components. Alternatively, Blazor components may
+ /// implement directly.
+ ///
+ public abstract class BlazorComponent : IComponent
+ {
+ ///
+ public virtual void BuildRenderTree(RenderTreeBuilder builder)
+ {
+ // This is virtual rather than abstract so that 'code behind' classes don't have to
+ // be marked abstract.
+ // Developers can either override this method in derived classes, or can use Razor
+ // syntax to define a derived class and have the compiler generate the method.
+ }
+
+ // At present, if you have a .cshtml file in a project with ,
+ // Visual Studio will run design-time builds for it, codegenning a class that attempts to override
+ // this method. Therefore the virtual method must be defined, even though it won't be used at runtime,
+ // because otherwise VS will display a design-time error in its 'Error List' pane.
+ // TODO: Track down what triggers the design-time build for .cshtml files and how to stop it, then
+ // this method can be removed.
+ ///
+ /// Not used. Do not invoke this method.
+ ///
+ /// Always throws an exception.
+ public virtual Task ExecuteAsync()
+ => throw new NotImplementedException($"Blazor components do not implement {nameof(ExecuteAsync)}.");
+ }
+}
diff --git a/src/Microsoft.Blazor/Components/RazorToolingWorkaround.cs b/src/Microsoft.Blazor/Components/RazorToolingWorkaround.cs
new file mode 100644
index 0000000000..fd6207f0d5
--- /dev/null
+++ b/src/Microsoft.Blazor/Components/RazorToolingWorkaround.cs
@@ -0,0 +1,43 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+/*
+ * Currently if you have a .cshtml file in a project with ,
+ * Visual Studio will run design-time builds for the .cshtml file that assume certain ASP.NET MVC
+ * APIs exist. Since those namespaces and types wouldn't normally exist for Blazor client apps,
+ * this leads to spurious errors in the Errors List pane, even though there aren't actually any
+ * errors on build. As a workaround, we define here a minimal set of namespaces/types that satisfy
+ * the design-time build.
+ *
+ * TODO: Track down what is triggering the unwanted design-time build and find out how to disable it.
+ * Then this file can be removed entirely.
+ */
+
+using System;
+
+namespace Microsoft.AspNetCore.Mvc
+{
+ public interface IUrlHelper { }
+ public interface IViewComponentHelper { }
+}
+
+namespace Microsoft.AspNetCore.Mvc.Razor
+{
+ public class RazorPage { }
+
+ namespace Internal
+ {
+ public class RazorInjectAttributeAttribute : Attribute { }
+ }
+}
+
+namespace Microsoft.AspNetCore.Mvc.Rendering
+{
+ public interface IJsonHelper { }
+ public interface IHtmlHelper { }
+}
+
+namespace Microsoft.AspNetCore.Mvc.ViewFeatures
+{
+ public interface IModelExpressionProvider { }
+}