

Show HN: Tonic – A data visualizing REPL for Node.js - boucher
https://tonicdev.com

======
nicolewhite
This is so amazing. It's like IPython notebook for node!

Edit: I made one[0]. I love that you force semantic versioning.

[0] [https://tonicdev.com/nicole/solve-a-cubic-
equation](https://tonicdev.com/nicole/solve-a-cubic-equation)

------
segphault
Really impressive and beautifully designed. I currently use Jupyter, but what
you've built feels a lot more polished and elegant.

Any plans to open the source code or make it available in a way that will
accommodate self-hosting? I'd really like to be able to use it to interact
with systems (like databases, for example) that are on my local network and
aren't practical to expose to the public internet.

~~~
tolmasky
The local option is something we're definitely trying to wrap our heads
around. Right now many of the features we offer are thanks to being hosted.
For example, the reason you have instant access to all 175,814 node packages
(and every version of those) is thanks to a pretty unique setup. On the other
hand we totally understand your use case and letting us know about it
certainly makes us take notice.

~~~
segphault
Thanks for the response. It's good to hear that you're thinking about local
access.

I realize that the node module thing is just one example of a feature that
relies on hosting, but fwiw I wouldn't mind having to manually maintain a
local package.json and node_modules folder for whatever libraries I want to be
able to use in the environment.

------
caffeinewriter
I'd love to see the ability to set environment variables, or some sort of
global variable behind the scenes, e.g. with credentials, so that they could
be used in code, without having to expose said credentials to the public,
similar to how some CIs do it, such as CircleCI. (Obviously with said
variables being cleared out on clones, or at least set to null, since
otherwise, editing said code would result in being able to just log out the
hidden data) Another alternative is having a public key available to encrypt
things with, allowing it to be decrypted by the server's private key.

Of course, I imagine this is a non-trivial feature, and there are likely
better approaches.

Super awesome job guys!

~~~
boucher
Check out
[https://tonicdev.com/settings/environment](https://tonicdev.com/settings/environment)

~~~
caffeinewriter
It would be nice to have a settings button on the notebook, along the side
with the publish/delete buttons, instead of having to go to Help -> The link
to environment variables, or the link from the homescreen. Just a thought :)

~~~
boucher
The settings UI is pretty... bare bones at the moment. We'll hopefully have
something much better in the near future.

------
savanaly
Great looking site and tool, I'm going to dig into it.

If I might start slinging feature suggestions right off the cuff:

\- I'm very used to using Cmd + Enter to "submit" a text area and you have
Shift + Enter. If I'm alone in expecting something different then of course
you shouldn't change it, but if I'm not you might want to consider changing
it.

\- Let me set the number of spaces in a tab. I'm used to two and while looking
at four isn't a game breaker, why tire out my fast thinking brain #1 trying to
parse something unusual? I would like to control it.

~~~
antouank
Agreed. Cmd+Enter is more commonly a way to submit something I think.
Shift+Enter is mostly used for adding a new line when Enter is reserved for
submitting.

~~~
boucher
Cmd + Enter should now work.

------
tolmasky
Hey guys, @boucher, @rentzsch and I are happy to get this out there, we are
around if you have any questions!

~~~
mcrowe
Beautiful work! Reminds me of a very polished Jupyter.

Any plans to support compile-to-js languages? Coffeescript, etc.

~~~
boucher
Possibly, depending on how much demand we see. You can obviously kind of
hackily use coffeescript right now by just requiring the package, but that's
not a real solution.

~~~
babby
I'd love CoffeeScript support.

Additionally... Tonic is comparible to CodePen in terms of testing and thus
gave me the idea;

Perhaps you could also include other languages into your platform. Such as a
Stylus REPL, SASS, SCSS etc. all of which, like CoffeeScript, are just JS
modules on npm.

With compilers like Stylus and SCSS you would probably default the return
value to be the compiled CSS, and with Coffee you'd need a toggle button to
show what the compiled JS looks like, though not 100% necessary.

With that said, if there was just a way to set up a "build" script for a REPL
to set up the environment to achieve the same result. As in, you
require('stylus') then have some global variable stream/buffer, tonic.output,
for which you could inject into the module of your choice to generate output,
and then save it via tonic.buffer.write() or something. It could then be
ridiculously flexible in terms of testing out finicky new languages/compilers.

------
lsjroberts
Not only does the tool look fantastic but so too does that landing page. I
look forward to using this, great work!

------
lmeyerov
Is there a reason to use this over a JS kernel within Juypter?

~~~
tolmasky
There's different tradeoffs of course, and we've obviously been inspired by
iPython and Mathematica and other interactive programming environments. Tonic
is in large part asking whether we can take the lessons of interactive
programming and make them useful to broader software development (hence a
focus for example on object viewers to analyze binary data). I think the
features called out in the site are pretty unique, but perhaps some conceptual
differences are warranted.

The key differences I would say are:

1\. The fact that you have access to every NPM package. Node is now the
environment with the most amount of packages, chances are someones solved part
of your problem already, why not have all that code at your fingertips?

2\. It was crucial in our mind to exactly match the behavior the code would
have if you ran it through node as if it were a straight file. That means, for
example, that every cell has to execute _synchronously_ after the last (not
async, you can't have ticks happen in between cells -- you're code will now
behave dramatically differently if you download it, especially in an
environment so dependency on asynchronous behavior like node). It really is
like a living file: even hoisting works -- you'll notice that if you modify a
function that is referenced in an earlier cell, Node will notify you that
you've "changed" the past, and will rerun from that point. This is very
different from the additive nature of iPython style repls where every cell
stomps on top of the last. In Tonic, no code that has run isn't on the screen:
because it really is like just running the file (again, you can download it
and run it yourself).

3\. Related to 1, notebooks are also easily publishable in a living way: a
node notebook _is_ just a node package. So you can require an notebook from
any other notebook, instant sharing.

4\. Our take on object viewers - we want these to be discoverable, not a part
of the code, its a view on the results. Tonic fundamentally deals with
Javascript objects, but the object viewers are applied on top -- post
execution you can decide to look at an image as an image, or hex viewer, or
download. An array could be a coordinate or a graph, both are available to you
to switch between, not a function you call to display your data. We really
want the tool to help you find new views on your data.

~~~
lmeyerov
I get this even less:

\-- For 1, that's analogous to having every python package via pip/conda, and
the same for other juypter langs.

\-- For 2, this is scary/hard for traditional notebook usecases. IPython gives
the user control, so there is no fear of beach balling & unintentional outside
effects. I do appreciate the intent however :)

\-- For 3, a notebook is just a json file and shareable. In fact, you can
share a _python notebook_ with a _js app_ and it'd still work. With maybe
50loc, you can even keep the require syntax.

\-- For 4, we're doing this within juypter just fine, and bokeh as well.

We recently went through a similar decision making process, and, when thinking
about the above and more, decided it'd be better for the community for us to
add features to Juypter than make yet another notebook. I don't think Juypter
is the end-all (though for none of the reasons above), so I'm still confused
here.

------
rjurney
This is neat, but what I really need to do is... import a time series and see
it plotted as line, bar, at different granularities, regress a trend line, do
anomaly detection. Make histograms, show me the mean/median/IQT/skew/etc (bar
charts at least?).

Is this stuff one-liners? Or is this a gimmick? If not, consider this a
feature request.

~~~
tolmasky
The goal of this project is to expose the power of node in the easiest way
possible. If a package exists to do the sort of analysis you're looking for,
then I think you will find it fastest with Tonic -- since you can search for
these things right in your product and _try them_. You can instantly include
two similar libraries and compare them, no search - install - remove loop. If
node gets better, Tonic gets better. Additionally, notebooks can also be
required, and we have primitive support for custom viewers through our HTML
viewer. If you publish a notebook that takes data and spits out amazing D3
graphs, we'll render them. Granted, what we have today is a start, but the
importance is how it can grow. And yes, for the record we have bar charts.

~~~
rjurney
I would write a charting library that uses d3 to let you chart in the repl.
Let me import a 1D array of numbers and make a histogram in one line. Let me
import a time series and plot that in one line.

This is meat. What you've got is fluff. No offense, its neat and you're
obviously capable of what I'm suggesting. Take on the core problem of charting
and you can create real value here.

~~~
tolmasky
Sorry, I think I misinterpreted your original post (apologies). I thought you
were saying "is this only good for one liners?", not "can this be done in one
line". Now that I further understand what you are saying, I can very
confidently say we are on the same page. What we have now should hint at what
we want: there's actually no _code_ to generate a graph, we interpret that any
array (or array of arrays, or array of objects that have the same keys) can be
interpreted as a graph. So we allow you to put that view _on_ the data after
the fact (as opposed to forcing you to learn the histogram function for
example). Under the hood this is done with some schema generation/sniffing and
query language. All this to say, the current graph viewer is certainly more
powerful under the hood -- and we'd definitely like to make the features you
requested _easily_ available. Again -- really sorry I misunderstood what you
were saying.

~~~
rjurney
Oh great to hear! Awesome.

------
caffeinewriter
This is exactly something I didn't know I was missing. Excellent tool! Looking
forward to trying it out.

------
lsjroberts
The publishing modal seems to have a couple of bugs:

1 - When trying to add release notes it closes the modal every time you press
a letter, though the letter is still there when you reopen the modal.

2 - After publishing a second time the modal can no longer be closed and
remains open until a full page refresh.

~~~
boucher
Thanks for the report, I'll take a look. Can I ask what browser you're using?
The hide on keypress thing doesn't seem to happen for me.

~~~
lsjroberts
Chrome 43 on OSX Yosemite. It seemed to work fine on the initial 1.0.0
publish, but it bugged out on the subsequent 1.0.1 etc publish attempts.

~~~
boucher
Thanks, it should be fixed once our next deploy pushes out.

------
toong
So, I see async/await and they refer to ES7. I think that's cheating a little
bit ?

I am interested in how they achieved very clean async/await support. I'm
assuming they are using some pre-processor.

Anyone more into the node-ecosystem can shine a light on this ?

~~~
feronull
[https://babeljs.io/](https://babeljs.io/)

------
z3t4
It wasn't until second visit I found this was a NodeJS emulator and WYSIWYG
editor. And not a graph maker.

It would be cool if you could plugin coding snippets to your own website. I'm
writing JavaScript tutorials and this would be very helpful.

------
mc_hammer
oh man this needs es6 support, this is so cool.

~~~
tolmasky
Apologies for not having full ES6 support yet, we actually do support a number
of ES6 features (like destructuring). The rest are mainly due to my laziness
(lack of time). The code undergoes a transformation where I need to know about
all the local variables in each cell for the time traveling feature, and
certain things like import statements add new local variables references that
I just haven't had the time to support so they're not whitelisted.

The feature in question is the following. We support hosting, so you could
have two cells like this:

[Cell 1] f()

[Cell 2] function f() { return 5; }

Normally "dirtying" is simple, if a cell from the past has changes, then the
future changes. However with hoisting, sometimes the future can change the
past. You'll see that in Tonic if you were to change the 5 to a 7, Cell 1
would appropriately dim letting you know the machine will go back to that
point to rerun.

~~~
mc_hammer
ok now that ive used it theres one thing i dont like:

* im changing code in a block but every time i eval it the 3 code blocks above re-expand the results i just hid... because the last one was `_ = require('lodash')` it prints like 70 lines of func defs :/

minor gripes:

* console.log(1,2) produces two lines of output, the browser version produces "1 2" (and then wraps every 3 lines, kind of inconvient when you log (i, array[i]))

* ctrl - y redo doesnt work (ctrl z does tho)

* the dom jitter from the results div disappearing, pause, appending "loading", then appending a large div, feels off. possibly lock the height, then replace contents w/ "loading", then transition to the new results size, if you can calculate that is better. really good tool tho gj.

really minor issues! im not logged in, idk if that matters

~~~
tolmasky
I am actually working on this exact issue right now :) Hopefully will be fixed
very soon.

Yeah the console.log thing is for when you have two objects, you want them on
two lines. However, we could get smarter and collapse lines (that were
together) if they have no fancy object viewers.

And yes -- I don't know why we chose three, we'll probably expand that.

Sorry about redo, it should work, we'll look into it.

------
scotty79
It would be even cooler if you implemented some compiled-to-js languages.

It's incredibly cool already. This could be start of beautiful blog platform.
I hope github buys you for crap load of money.

------
brownBananas
The stylesheets aren't loading for me. Let me know where I can send you
information to help you reproduce this.

------
Frozenlock
What is the command to load a json API? (Which requires to set the content-
type header...)

~~~
boucher
I recommend requiring "request-promise", which is a drop in replacement for
"request". Here's the docs on sending custom HTTP headers with that package:
[https://www.npmjs.com/package/request#custom-http-
headers](https://www.npmjs.com/package/request#custom-http-headers)

~~~
Frozenlock
Thanks!

------
vladikoff
Some modules return "Error {code: "MODULE_NOT_FOUND"}" why is that?

~~~
boucher
Although we have every package, not every package with binary dependencies
builds easily. So some of those will show up as not being available. But if
you send us an email with the package info we'll fix it.

------
PabloOsinaga
what about a visualization for mongo cursors? ( ala robomongo ). I feel the
use case for me would be ad-hoc querying/analysis of data in mongo - so that'd
be critical

~~~
boucher
Could be pretty cool. One thing you can _almost_ do is make custom
visualizations. There's an HTML viewer, so if you can build a function that
turns an object into html, you can build yourself a custom display. We're
hoping to make this easier though.

------
taternuts
This is incredible, I plan on using this a lot. Thanks!

------
euroclydon
So it's a SaaS? Or can it be run locally?

~~~
boucher
It can't be run locally. Some of the feature we've built would be really
difficult if not impossible to run offline. That said, maybe someday a paired
down version for local use would make sense.

~~~
clessg
So it can't be used to replace the built-in REPL and play with your
unpublished modules? That's a shame; the built-in node REPL has never been
pleasant to work with. I would definitely pay money for a local version of
this.

~~~
boucher
Good to know :). We have some ideas on how we might integrate with local
files, hopefully we'll be trying some of them soon.

~~~
d--b
you could use electron (used to be atom-shell). It would be perfect for that!

------
thingsilearned
Super awesome. Well done guys!

------
d--b
boucher: Did you release this now as a response to the release of Eve (version
0)?

~~~
boucher
Nope. That team is doing really interesting work.

------
CyberDildonics
This looks like a verbatim ripoff of Juno, but I don't see any credit given to
Juno or Mike Innes. It looks like they even cloned his site or used the same
template.

[http://junolab.org/](http://junolab.org/)

~~~
boucher
Thanks for pointing out Juno, looks like a useful tool. I had never heard of
it before, and it did not influence our work. I suspect some things might look
similar to you since some of both of our websites use bootstrap, but I'd go so
far as to say that I don't agree that they look very much alike or that anyone
would confuse our product for Juno.

