# How to integrate Julia with a HTML web page?

**URL:** <https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019>\
**Category:** New to Julia\
**Tags:** question, package, http\
**Created:** [October 9, 2020, 8:00am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019 "2020-10-09T08:00:16Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![yasser\_rajwani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yasser_rajwani/32/14278_2.png) [@yasser\_rajwani](https://discourse.julialang.org/u/yasser_rajwani)\
**Post date:** [October 9, 2020, 8:00am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/1 "2020-10-09T08:00:16Z")

</div>

How to call a Julia function from an application running in a web browser

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 9, 2020, 10:29am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/2 "2020-10-09T10:29:20Z")

</div>

I believe you want:

[https://github.com/JuliaWeb/WebSockets.jl](https://github.com/JuliaWeb/WebSockets.jl)

(or one of the alternatives mentioned there, OR this latest package):

[https://github.com/citkane/SimpleWebsockets.jl](https://github.com/citkane/SimpleWebsockets.jl)

[EDIT: It used to be called Websocket.jl when I originally wrote this post, was renamed, see link at the bottom.]

I noticed the latter package registered a few days ago, but now when looking into it, it seemed to have years of development, and I was confusingly looking at the former package…

I do not know too much about these packages, or the standardized API, but I believe it’s exactly what you’re looking for. You would runs some JavaScript code in the web browser to access the Julia websocket. In general you can compile Julia code to JavaScript too, with JSExpr.jl, but I’m not sure if it helps with this, at least that would be optional.

> [@\[ANN\] Websocket - High level API for Server and Client with documentation](https://discourse.julialang.org/t/ann-websocket-high-level-api-for-server-and-client-with-documentation/47957):
>
> Websocket.jl [[image]](https://citkane.github.io/Websocket.jl/stable) [[image]](https://citkane.github.io/Websocket.jl/dev)[Github Code](https://github.com/citkane/Websocket.jl)Why another Websocket package? The existing Julia websocket solutions are in various states of development and lack comprehensive high level API’s comparable to offerings in other languages such as JS and Python. For this reason I have ported the architecture of the popular Node.js [websocket](https://www.npmjs.com/package/websocket) package into Julia. Basic usage server: using Websocket server = WebsocketServer() ended = Condition() listen(server, :client) do client listen(client, :me…

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [October 10, 2020, 12:26am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/3 "2020-10-10T00:26:57Z")

</div>

An alternative approach is to host your page using Genie.jl. Depending on what you want, this can be highly advantageous. I’ve been doing this for a web app at work, and I can ring down to shell via `run()` send emails with postmail, use LibPQ to crunch some numbers, log activity, upload files via genie+html forms, and spit out some pretty css/html to say what is happening, open JIRA issues via the REST API. All with Julia at the middle. Julia is almost made for the web - except it’s not yet…

---

<div class="post-metadata">

**Author:** ![citkane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/citkane/32/17595_2.png) [@citkane](https://discourse.julialang.org/u/citkane)\
**Post date:** [October 10, 2020, 12:48pm UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/4 "2020-10-10T12:48:32Z")

</div>

Please consider [SimpleWebsockets](https://discourse.julialang.org/t/ann-simplewebsockets-renamed-from-websocket/48050) and not `Websocket`. I was asked to rename the package to be more distinct from `JuliaWeb/WebSockets`.

Sorry about the confusion.

---

<div class="post-metadata">

**Author:** ![yasser\_rajwani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yasser_rajwani/32/14278_2.png) [@yasser\_rajwani](https://discourse.julialang.org/u/yasser_rajwani)\
**Post date:** [October 14, 2020, 9:48am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/5 "2020-10-14T09:48:58Z")

</div>

Thank you for your reply,  
could you please share more detail ?

What I am looking for is an application / process that would allow me to run Julia, without having to manually trigger it every time.

Ideally through VBA or hosting it on a server

---

<div class="post-metadata">

**Author:** ![citkane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/citkane/32/17595_2.png) [@citkane](https://discourse.julialang.org/u/citkane)\
**Post date:** [October 14, 2020, 2:55pm UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/6 "2020-10-14T14:55:39Z")

</div>

As a generic technology solution for this, you could consider [Remote Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call) solutions such as [GRPC](https://grpc.io/). There is no official Julia support for GRPC, but I have spotted some work on Github towards this.

Another approach would be to implement a [messaging BUS](https://www.enterpriseintegrationpatterns.com/patterns/messaging/MessageBus.html) architecture with any of the many solutions such as Kafka, ZeroMQ, RabbitMQ, MQTT, etc, etc…

And as mentioned before, you can achieve the same using messaging over [websockets](https://en.wikipedia.org/wiki/WebSocket).

Or http request / response with a http server on your Julia instance.

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [October 14, 2020, 4:37pm UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/7 "2020-10-14T16:37:47Z")

</div>

I did a similar proof of concept a while back that you can check out here:

Backend API:

[https://github.com/mthelm85/JuliaAPI](https://github.com/mthelm85/JuliaAPI)

Client side (built with Vue.js):

[https://github.com/mthelm85/JuliaAPIClient](https://github.com/mthelm85/JuliaAPIClient)

I have the Julia API running on a free Heroku dyno and the client running on another free Heroku dyno:

Client: [https://julia-api-client.herokuapp.com/](https://julia-api-client.herokuapp.com/)  
API: [https://julia-api-example.herokuapp.com/addxy](https://julia-api-example.herokuapp.com/addxy)

It’s not set up properly so if you test the client app in your browser it throws a network error and you have to wait and keep clicking “Compute” but it will eventually return something ; )

You can also just play with the API endpoint by doing something like this:

[https://julia-api-example.herokuapp.com/addxy?x=4&y=4](https://julia-api-example.herokuapp.com/addxy?x=4&y=4)

which will return the sum of x and y (8).

It’s strange, I just played with it now for the first time in a long time and when everything starts up it’s really slow and clunky but once you compute a few sums it seems to speed up a bit. I know those free Heroku dynos go into some sort of hibernate mode and have to wake up once someone makes a request to the URLs but I’m not sure why it seems to need to “warm up” to get going.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [October 15, 2020, 10:26am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/8 "2020-10-15T10:26:33Z")

</div>

For a more high level example see also [this post](https://discourse.julialang.org/t/make-a-webapp-framework-ecosystem-as-awesome-as-rs-shiny-a-challenge-to-julias-community/9533/40) that uses Interact + Mux.

EDIT: I saw now your other post on this thread, maybe this is not what you want… if your only need is to not “manually” run the application you could maybe just use the cron system of your server ?

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [October 15, 2020, 10:38am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/9 "2020-10-15T10:38:26Z")

</div>

Please share with us what the Julia code is doing - what sort of task? Also the enviironment where you want the code to run.

---

<div class="post-metadata">

**Author:** ![citkane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/citkane/32/17595_2.png) [@citkane](https://discourse.julialang.org/u/citkane)\
**Post date:** [October 15, 2020, 11:24am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/10 "2020-10-15T11:24:36Z")

</div>

This is the shortest, most ridiculously unsecure, bare metal way to remote control a Julia process from a html page I could think of using a websocket connection:

## Julia

```Julia
using Pkg
Pkg.add(name = "SimpleWebsockets", version = "0.1.4")
using SimpleWebsockets

server = WebsocketServer()

listen(server, :client) do ws   
    listen(ws, :message) do message
        try
            comm = Meta.parse(message)
            result = Base.eval(@ __MODULE__ , comm)
            send(ws, string(result))
        catch err
            @error err
            send(ws, "Could not run command")
        end
    end
end
function echo(val)
    return val
end
serve(server, 8081)

```

## HTML (tested on Firefox)

```html
<!doctype html>
<html lang='en'>
<head>
    <meta charset='utf-8'>
    <title>Websockets are awesome</title>
    <style>
        body {
            font-family: sans-serif;
            height: 100vh;
            padding: 0;
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        input {
            margin: 4px 0;
        }
    </style>
</head>
<body>
    <form onsubmit='event.preventDefault(); sendcommand();'>
        <label>Enter a Julia command:</label><br>
        <input
            type='text'
            placeholder='eg. 1+1 or echo("hellooooo..")'
            id='command'
        />
        <span id='result'></span><br>
        <input type='submit' value = 'Send command'>
    </form>
    <script>
        input = document.getElementById('command');
        result = document.getElementById('result');
        const ws = new WebSocket('ws://localhost:8081')
        ws.addEventListener('message', message => {
            result.innerHTML = ` = ${message.data}`
        })
        function sendcommand(){
            ws.send(input.value)
        }
    </script>
</body>
</html>

```

Uses port 8081, but that can be adjusted as you like.

Start the Julia code locally, save the HTML to `index.html` and open it locally in your browser.

---

<div class="post-metadata">

**Author:** ![GregMcC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregmcc/32/14827_2.png) [@GregMcC](https://discourse.julialang.org/u/GregMcC)\
**Post date:** [March 29, 2021, 11:44am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/11 "2021-03-29T11:44:19Z")

</div>

“It’s Slow to start” - Isn’t that because Julia is a compiled language ?

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [March 29, 2021, 12:39pm UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/12 "2021-03-29T12:39:15Z")

</div>

In this case I don’t believe that has anything to do with it as it’s just a simple sum function - I’m almost certain it’s a Heroku dyno thing. I don’t know that the Julia session ever actually shuts down - I think it’s just the dyno that goes to sleep (so it shouldn’t be recompiling anyting). I’ve hosted other applications on their free tier dynos and sometimes they seem to need to be jolted back to life by a few requests 😄

In this case, the client is on one dyno and the API is on a second dyno so the client has to wake up, call the API, the API dyno has to wake up, then do the calculation and send the answer back to the client. I’m sure if these were on the paid-tier dynos they would run smoothly and without issue.

---

<div class="post-metadata">

**Author:** ![worldsayshi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/worldsayshi/32/42937_2.png) [@worldsayshi](https://discourse.julialang.org/u/worldsayshi)\
**Post date:** [September 24, 2022, 10:42pm UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/14 "2022-09-24T22:42:32Z")

</div>

Please be very careful when following this advice since it will allow anyone who can access the web page to do whatever they want to the server.

To make it infinitely safer don’t read code that someone sends over the internet. Instead just trigger a prewritten script.

---

<div class="post-metadata">

**Author:** ![Alex1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex1/32/11771_2.png) [@Alex1](https://discourse.julialang.org/u/Alex1)\
**Post date:** [July 13, 2024, 10:15am UTC](https://discourse.julialang.org/t/how-to-integrate-julia-with-a-html-web-page/48019/15 "2024-07-13T10:15:16Z")

</div>

Don’t overcomplicate, to connect Browser JS to Julia all you need is half a page of code. Don’t use message busses, RPC frameworks, WebSockets and all sorts of other complicated things unless you are good paid to waste your time overengineering it.

Use any julia web server implemeting single `/server/rpc` route, and this code in the browser:

```julia
async function call_server_function(fn: string, args: any[]): Promise<any> {
  const res = await fetch(
    `/server/rpc`, 
    { method: 'POST', headers: { 'Content-Type': 'application/json' },  
    body: JSON.stringify([{ fn, args }]) 
  })
  return await res.json()
}

```

And if you need to initiate some task from the server, server push etc, this:

```julia
setInterval(async () => {
  const result = await call_server_function('server_push', [])
  if (result) do_something_with(result)
}, 200)

```

And when you make your app work, and for some reason need to scale it to millions of users (modern servers would easily handle hundreds and thousands requests/sec with this setup), then you may invest more time and build more complicated and performant solution.
