diff --git a/examples/remote/README.md b/examples/remote/README.md
new file mode 100644
index 00000000..c5fb5ff6
--- /dev/null
+++ b/examples/remote/README.md
@@ -0,0 +1,23 @@
+This this example Neovim plugin shows how to invoke a [Go](https://go.dev/)
+function from a plugin.
+
+The plugin starts a Go program containing the function as a child process. The
+plugin invokes functions in the child process using
+[RPC](https://neovim.io/doc/user/api.html#RPC).
+
+Use the following steps to run the plugin:
+
+1. Build the program with the [go tool](https://golang.org/cmd/go/) to an
+   executable named `helloremote`. Ensure that the executable is in a directory in
+   the `PATH` environment variable.
+   ```
+   $ cd helloremote
+   $ go build
+   ```
+1. Install the plugin in this directory using a plugin manager or by adding
+   this directory to the
+   [runtimepath](https://neovim.io/doc/user/options.html#'runtimepath').
+1. Start Nvim and run the following command:
+   ```vim
+   :Hello world!
+   ```
diff --git a/examples/remote/helloremote/go.mod b/examples/remote/helloremote/go.mod
new file mode 100644
index 00000000..52caefcd
--- /dev/null
+++ b/examples/remote/helloremote/go.mod
@@ -0,0 +1,5 @@
+module example.com/remote/helloremote
+
+go 1.22.2
+
+require github.com/neovim/go-client v1.2.1
diff --git a/examples/remote/helloremote/go.sum b/examples/remote/helloremote/go.sum
new file mode 100644
index 00000000..c2c1b644
--- /dev/null
+++ b/examples/remote/helloremote/go.sum
@@ -0,0 +1,2 @@
+github.com/neovim/go-client v1.2.1 h1:kl3PgYgbnBfvaIoGYi3ojyXH0ouY6dJY/rYUCssZKqI=
+github.com/neovim/go-client v1.2.1/go.mod h1:EeqCP3z1vJd70JTaH/KXz9RMZ/nIgEFveX83hYnh/7c=
diff --git a/examples/remote/helloremote/main.go b/examples/remote/helloremote/main.go
new file mode 100644
index 00000000..591c769f
--- /dev/null
+++ b/examples/remote/helloremote/main.go
@@ -0,0 +1,40 @@
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"strings"
+
+	"github.com/neovim/go-client/nvim"
+)
+
+func hello(v *nvim.Nvim, args []string) error {
+	return v.WriteOut(fmt.Sprintf("Hello %s\n", strings.Join(args, " ")))
+}
+
+func main() {
+	// Turn off timestamps in output.
+	log.SetFlags(0)
+
+	// Direct writes by the application to stdout garble the RPC stream.
+	// Redirect the application's direct use of stdout to stderr.
+	stdout := os.Stdout
+	os.Stdout = os.Stderr
+
+	// Create a client connected to stdio. Configure the client to use the
+	// standard log package for logging.
+	v, err := nvim.New(os.Stdin, stdout, stdout, log.Printf)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Register function with the client.
+	v.RegisterHandler("hello", hello)
+
+	// Run the RPC message loop. The Serve function returns when
+	// nvim closes.
+	if err := v.Serve(); err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/examples/remote/plugin/hello.lua b/examples/remote/plugin/hello.lua
new file mode 100644
index 00000000..50986ce5
--- /dev/null
+++ b/examples/remote/plugin/hello.lua
@@ -0,0 +1,14 @@
+local chan
+
+local function ensure_job()
+  if chan then
+    return chan
+  end
+  chan = vim.fn.jobstart({ 'helloremote' }, { rpc = true })
+  return chan
+end
+
+vim.api.nvim_create_user_command('Hello', function(args)
+  vim.fn.rpcrequest(ensure_job(), 'hello', args.fargs)
+end, { nargs = '*' })
+