
PyPy.js: Python in the web browser - LopRabbit
https://pypyjs.org/
======
amasad
It's really awesome to see how far this has come. I believe we at Repl.it were
the first to try something like this in production. We emscriptined CPython to
JavaScript and contributed quite a bit to the project in the process
(including the initial virtual filesystem implementation).

[https://github.com/replit-archive/empythoned](https://github.com/replit-
archive/empythoned)

I deployed this at scale at Codecademy were millions of users were using it to
learn Python but hit a lot of problems with it. For one, if you're in a 3rd
world country then the bundle size is a non-starter (this is potentially
solved with WASM being a binary format). Even if you managed to download the
bundle lots of old computers would run out of memory trying to parse the JS
(again probably solved by the binary AST format of WASM). Because of this and
a few other issues (the dev experience of emscripten was really hard) we had
to move away to running code on remote containers.

Now that I'm back working on Repl.it full time I'm excited to play again with
the tech and see what we can do with it this time around.

~~~
flanbiscuit
I just wanted to say how much I love Repl.it and use it all the time. I use it
as a testing scratchpad mostly but I know it's much powerful than that. I
appreciate its simplicity. Thanks for a great product!

~~~
amasad
Thanks so much :)

------
hathawsh
I'm curious about the virtual filesystem:

    
    
      Welcome to PyPy.js!
      >>> import os
      >>> os.listdir('/')
      ['tmp', 'home', 'dev', 'lib']
      >>> f = open('/what', 'w')
      >>> f.write('hey')
      >>> f.close()
      >>> os.listdir('/')
      ['tmp', 'home', 'dev', 'lib', 'what']
      >>> open('/what').read()
      'hey'
    

What is in the stack that makes that work?

~~~
mattigames
The Emscripten File System API, "The API is inspired by the Linux/POSIX File
System API, with each presenting a very similar interface."
[https://kripken.github.io/emscripten-
site/docs/api_reference...](https://kripken.github.io/emscripten-
site/docs/api_reference/Filesystem-API.html)

~~~
hathawsh
Thanks!

------
lucb1e
The speed is surprisingly reasonable. Testing with a simple loop, I get about
1.3-1.4 million loops per second in python3, 2 million loops per second in
python2, 14.5 million loops in pypy, and 0.61 million loops in the browser.

My code basically calls int(time.time()) until its value changes, doing i+=1
for every time it did not change (n=10 for every platform
(python2/3/pypy/browser)). My browser is Firefox 61, full code here:
[https://hastebin.com/turenofise.py](https://hastebin.com/turenofise.py)

~~~
tim333
Though trying to add the numbers for 1 to a million in a loop javascript was
about 10 - 20 times faster when I tried it.

~~~
sametmax
You would use sum(range()) in a Python though. Remember that many things you
do manually in JS have a better, automatic and faster way in the stlib.

Besides, if calculations are important, you would use numpy.

~~~
tim333
Ah yes. sum(range()) in Python vs for(i=1...) in js was much closer, about 20%
quicker in javascript.

~~~
gengkev
Won't this calculation overflow to +Infinity in JavaScript after a while? On
the other hand, Python will try to compute the actual result using arbitrary
precision integers, which is that's slower.

------
veganjay
There is a similar Python interpreter here:
[http://www.codeskulptor.org/](http://www.codeskulptor.org/)

It is used by a class taught on Coursera (Introduction to Interactive
Programming in Python)

From what I can see:

\- PyPy.js benefit: runs faster

\- codeskulptor benefit: can use GUI components

------
adamwiggins
Great project. My team used it for a live-coding Python notebook:
[https://github.com/inkandswitch/livebook#readme](https://github.com/inkandswitch/livebook#readme)

To my surprise it was faster than Jupyter / CPython for some tasks (e.g.
loading and parsing large CSVs).

~~~
dunpeal
Shouldn't be too surprising, given how PyPy is generally faster than CPython
by about x7-8 factor:

[http://speed.pypy.org/](http://speed.pypy.org/)

I'd expect a much larger difference in tasks that are pure Python (loading a
CSV is done primarily through the csv module, i.e. all the hot loops are in
C).

~~~
icebraining
Yes, but PyPy is usually compiled to machine code (and emits machine code),
not to JS.

~~~
azakai
True, but the asm.js is then compiled to machine code by the browser's JS JIT.

I'd expect some overhead from sandboxing etc., but it should be fairly close
to native speed.

~~~
ris
It's not "overhead from sandboxing" that's a problem, it's the fact that
translating from bytecode to bytecode to bytecode will cause it to lose some
... succinctness at each step, giving the final machine code generator a
harder time coming up with efficient code for it.

------
VectorLock
I'd love there to be a client-side webapp development system using Python with
feature and output parity to JavaScript. If it was a product, I would buy it.

~~~
rkeene2
I've been thinking about building this for Tcl. Tcl has been available in the
browser in various forms for decades, but one thing that makes Tcl uniquely
suited to a web application style development is its threading model. In Tcl,
you access a thread by sending messages to it, in which a Tcl interpreter
inside its event loop processes. My plan was to have a client-side Tcl program
in the browser that automatically instantiates a second thread, but the thread
is a remote thread running on the server, so you would be able to access the
server just as if it were another thread.

Something like (client-side):

    
    
        thread::send $::tcl-web::server -async {
            do stuff
        } placeToStoreResult
        ...
        vwait placeToStoreResult
        do stuff with result $placeToStoreResult

~~~
typon
But then you have to code in... Tcl...

~~~
rkeene2
Then you GET to code in Tcl !

~~~
justbaker
>Then you GET to code in Tcl ! I don't care about Tcl but your enthusiasm is
golden. Sort of why I write silly stuff in bash or in an esoteric manner;
"Why" "Cause we can!!"

------
tony-allan
Pity it's not Python3.

~~~
rtkwe
Yeah weird. I would expect Python2 to be dying off more by now. Wonder if
we're headed to an environment where there's essentially 2 separate languages
as Python 3 continues to change and grow?

~~~
jchw
I think we're roughly already there. I think the pivotal moment where Python 2
could've died out rapidly passed and they kept officially supporting it for
too long.

~~~
da_chicken
As far as I know, permanent EOL for Python 2 is still Jan 1, 2020
([https://pythonclock.org/](https://pythonclock.org/)). Python 3 was first
released December of 2008. That's an awfully long tail.

~~~
collinmanderson
Fascinating. I always thought Python 2.7 support would end July 3, 2020
(exactly 5+5 years from when 2.7 was released), but for some reason they
recently decided to go with Jan 1st.

> Specifically, 2.7 will receive bugfix support until January 1, 2020. All 2.7
> development work will cease in 2020.

> I've updated the PEP to say 2.7 is completely dead on Jan 1 2020. The final
> release may not literally be on January 1st, but we certainly don't want to
> support 2.7 through all of 2020.

[https://www.python.org/dev/peps/pep-0373/#maintenance-
releas...](https://www.python.org/dev/peps/pep-0373/#maintenance-releases)
[https://mail.python.org/pipermail/python-
dev/2018-March/1523...](https://mail.python.org/pipermail/python-
dev/2018-March/152355.html)

------
wietze
The most important import doesn't work, unfortunately:

    
    
      import antigravity

~~~
cybersol
At least all is not lost:

    
    
      Welcome to PyPy.js!
      >>> from __future__ import braces
        File "<console>", line 1
      SyntaxError: not a chance
      >>>

------
duhi88
This is pretty old, and hasn't seen an update in over a year. I never
understand why links links this get posted with no discussion to start it off
with.

Also, wouldn't this be better implemented with WASM?

~~~
anarchy8
> This is pretty old, and hasn't seen an update in over a year

So pretty much like every Python project then. What's happening to the Python
community?

~~~
digitaLandscape
It's stable and mature?

If you've been writing JavaScript your whole career you might not know what
that looks like.

~~~
Waterluvian
Such a snarky response, but I can't deny it. I see a JS package that hasn't
been updated in a year and I expect that it won't even build with my
environment because webpack evolution. I see a python package that hasn't been
updated in a year and it doesn't faze me. Not a whole lot that can break in
terms of building and integration with my python project.

~~~
andrewmcwatters
Perspective is everything. Now and again I use C libraries that haven't been
updated in 15 years. Why? There isn't a need. Everything builds perfectly, and
some of those libraries are still the go-to solutions in my field.

------
costrouc
Will web assembly have any effect on a future web based python interpreter? Is
there one in the works?

~~~
aylmao
Someone posted this on another thread: [https://github.com/iodide-
project/pyodide](https://github.com/iodide-project/pyodide)

What I gather is that it's compiling CPython to WASM and ships it along with
some other utilities. It looks pretty cool.

------
ipsun4
Tried Fibonacci, and the thing crashed for 100. I'm not sure that a wasm
python library can do any heavy lifting.

------
jokoon
seems brython is more appropriate, mature and usable.

------
klhugo
I tried to do a little something with Emscripten and WebAssembly, but I
stopped on the sockets implementation. It relies on WebSockets. I wonder how
well we could emulate real sockets using WebRTC to make WebAssembly apps more
sophisticated.

~~~
IshKebab
Last I looked Emscripten already used WebRTC's data channel to emulate UDP.

------
askvictor
Is there an up-to-date/maintained comparison of python-in-the-browser systems?
As well as this, there's brython and skulpt, and it would be nice to be able
to compare various implemented features, quirks and speed.

------
imh
Really amazing. I use python every day at work, and most of the crucial
libraries have tight inner loops written in C or Cython. I wonder what the web
assembly future holds for those languages, and inter-language FFI.

------
slezyr

        >>> os.getlogin()
        'root'
    

Nice joke :)

------
cutler

      File "<console>", line 2
        return f'{fname} {surname} is {age}.'
               ^

SyntaxError: invalid syntax

So this is a subset of Python or something like that?

~~~
Nicksil
I believe this feature was introduced in Python 3.6. This implementation may
be 3.6 <

Edit: Just checked the site and see it uses PyPy which states -- on their site
-- the python version is 3.5.3

~~~
zorkw4rg
I can't do:

a, *b = range(3)

which should be 3.5 i think.

~~~
Nicksil
Other comments in this thread point to the implementation likely being Python
2.x.

------
nichochar
This is awesome. They mention that it is a "compliant" implementation of
python. How does one go about proving this?

~~~
tathougies
There's no python standard, but my guess is that-- since this is based on the
same source code that native PyPy is, with a different compiler backend --
they are making the claim based on the fact that native PyPy is widely
considered to be similar enough to CPython for many workloads. Thus --
assuming the correctness of the RPython -> JavaScript transformation (which
they have not proven, and would be a monumental task) -- you should expect
this version to work like the native PyPy.

------
parabx
this is pretty neat! I was wondering, are there any projects to transpile
python to js, but targeting the server side? It would be interesting to port a
flask application, for example, to run on node and benefit from the jit, or
maybe use express and call flask through its wsgi interface.

~~~
icebraining
You're better off running it on the original version of PyPy, which already
uses a JIT.

------
nautilus12
Why use this instead of jupyter? Some educational applications maybe?

~~~
antoineMoPa
I think jupyter works with a backend server to execute python (right?).

~~~
Waterluvian
Correct. It's just a view to a server running python.

------
mfoy_
Would it be sane to use this to run Python modules in node.js?

~~~
kodablah
If the Python module was large and complex, it does something that would be
incredibly difficult to replicate in nodejs either given the current ecosystem
or costs of a rewrite, is not available in Rust/C/C++ that could be WASM'd
(not mentioning others here due to large WASM overhead), you accept the large
binary sizes of these things (i.e. you're not embedding the Python
interpreter/runtime and putting on npm), and you're willing to put a node-
friendly layer on top that makes the lower level calls...then it might be
sane. But I'd consider modernizing to an updated emscripten that does WASM,
see if you can avoid some emscripten runtime (i.e. WASM standalone
compilation).

For all other cases, stay in Node or use a lib from a language more suited to
WASM compilation. Now, if it's an option between this and a native Node
module, that depends on your opinion of Node FFI and native Node modules.

------
fhood
>>> print "hello"

hello

>>>import json

>>>

Dope, everything I need.

------
msoad
Jeff Atwood law of Javascript

    
    
        everything that can be written in JS will be written in JS!!

------
trumped
is that interpreter faster then the default one?

------
inetknght
* >>> import sys >>> sys.version '2.7.9 (?, Jul 03 2015, 17:08:29)\n[PyPy 2.6.0]' *

Why, exactly, does this have such a garbage-ancient version of Python?

------
Alupis
Didn't we decide a long while back that fully featured programming languages
were dangerous in the browser, especially if they could do disk I/O? Even if
sandboxed? A la Java Applets and Adobe Flash?

    
    
        import os 
        for subdir, dirs, files in os.walk('./'): 
            for file in files: 
              print file 
              os.remove(file)
    

Perhaps the environment is "fake", and these files don't really exist, even in
some sandbox... otherwise, seems like this might pose a security risk.

~~~
lucb1e
This is Javascript, not real Python. If you're so afraid that this is
dangerous, why do you post malicious code? And if you're so clever to post
that code, why don't you try similar code to see if it really has access to
your files?

    
    
        import os
        os.listdir('/')
    

The answer, by the way, is no.

~~~
Alupis
> If you're so afraid that this is dangerous, why do you post malicious code?

That's not malicious code... it removes files from a sandbox... you can
refresh the page and see for yourself.

> And if you're so clever to post that code

There's no need to be rude... there's an honest question and lack of
understanding in my post - educate me, don't talk down to me.

> why don't you try similar code to see if it really has access to your files

The question was if someone could break out of a sandbox, such as with Java
Applets and Adobe Flash. I have no idea how to do that - I'm not a security
specialist, nor some sort of hacker guy.

> The answer, by the way, is no.

From the sandbox and using the standard `import os`, ya, you're right. The
question, again, is what if someone got outside the sandbox?

~~~
Macha
Well why doesn't this apply to JS? The python interpreter is running in the JS
sandbox

~~~
Alupis
I suppose that was the explanation I was looking for.

