Dynamically compile & execute go code at runtime

Can I dynamically compile & execute the go code as a string at runtime ?

I am just a beginner to golang
Expecting somewhat like this.

// main.go
package main

import (
     goc "some/package/to/compile/go"

func main() {
      some go code ...

As a result, If I run the file

go run main.go

I am expecting to get the output of the code written as the string

Are there any packages to do this ?

Thanks In Advance

Hi @soubikbhuiwk007, welcome to the forum!

What would you need this for?

I am asking because compiling Go needs more than just a compiler package. The whole toolchain must be available, too, in order to download external modules etc. Also, the standard library has to be available for this to work.

Hence you could simply install Go on the target system and have your code call the compiler via the os/exec package.

Maybe have a look at how Go REPLs (Read-Eval-Print-Loop) do it. For example,

simply use an installed Go toolchain.

Thanks, @christophberger

Well, I was making a cli in which you could download the source code from a URL and execute it.

It was going fine, if the source had no input prompt. Now to make this possible, I was looking for the someway to do it and the only way came to my mind was to compile and execute the source.

Are there any other way to get this work done ?

What is the underlying problem that your cli shall solve?

Perhaps your cli could simply download and install the Go toolchain first and use it for compiling. Go can be “installed” as easily as downloading a tar.gz or zip file and unpacking it to somewhere.

Let’s say I have a following program from a URL

I expect the user to already have go installed

package main
import "fmt"
func main() {
    var name string
    fmt.Print("Enter Name: ")
    fmt.Printf("Hello %v", name)

I want the code above to execute as a part of my program (CLI-Name: urlgo)

In terminal, if I run this:

$ urlgo run <url>


Enter Name: soubik
Hello soubik

Are there anyways of doing this instead of compiling the code.

What is the use case? Why do you need the code execute as part of your program, rather than compile the code and call it as an external executable?

Maybe there is an easier way to achieve the underlying goal.

For example, does the code behind the URL have to be Go code? There are a couple of script language integrations available for Go, such as Lua or JavaScript. Basically, these are packages that provide interpreters for these scripting languages. If the code that you download from the URL is a Lua or JavaScript script, you can run it right away inside your Go binary.

And another question is, do you want to download and execute code from a URL at all? Consider all the security risks involved.

Your first post is a packager idea (e.g. like apt, rpm, snap, etc in Linux OS; or Apple/Windows/Play Store). You just need to focus on developing that as a development direction where you just need to comply some kind of distribution rules (e.g. https://wiki.debian.org/DebianRepository/Format) or define your own.

Also, I’m confused with your latest example which sounds like a simple downloader: are you looking for flag llibrary? If you want high tech savvy version, cobra and/or viper should do the trick. As for downloads, you can take a look at a lot of download examples (e.g. https://golangbyexample.com/download-image-file-url-golang/).

Anything below for the downloader idea is overkill in my opinion. If I place my bet, you won’t be needing it. I’m listing them out since I don’t know what’s in your mind and what’s the actual idea.

If you’re looking for dynamic scripting in Go (e.g. python via cython under the hood) intepreter, you can take a look at tengo project. Don’t go for “shell interpreter” libraries. If I’m gonna shell, I just shell it with os.Execute; It doesn’t need to creep into Go binary.

If you’re looking for something like dynamic loading, Go has native plugin library for you to dynamically load compiled Go binary and use it on-the-fly.

Yes, I didn’t consider the security issues. Thanks for reminding.