Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Tonic – A data visualizing REPL for Node.js (tonicdev.com)
342 points by boucher on Aug 18, 2015 | hide | past | web | favorite | 79 comments

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

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.

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.

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.

Two things.

First of all, I think that both hosted and downloadable models are both equally viable, and IMHO both are worth pursuing simultaneously.

While I discuss the merits of a downloadable version below, first of all, staying hosted makes a lot of sense, not just because delivering all of npm is... tricky (kudos for managing to provide it :P), but also because it gives you the option to introduce a pricing structure in the future. (That said, please definitely do keep your current featureset free. XD)

A Google Maps Overlay[1]-style API could be a viable solution for developers who choose to use your hosted system who also need access to local resources: I'm thinking something SSL-encrypted (using symmetric keys configured via a dashboard), and perhaps a small (opensource, auditible) endpoint library that connects to your server (over WebSocket or XHR, to work around pesky firewalls), which the developer would be able to connect to the relevant bits of their data with a minimum of SLOC. (I'm not sure if it's outrageously unsuitable - it's probably only useful as an idea - but Netflix' newly-released Falcor library[2] comes to mind.)

I also think a cut-down version of your system could be a very very interesting competitor to Jupyter/IPython, and it's (reasonably) rare for competition to be a bad thing.

(Looking at the whole picture, there will undoubtedly be political types who will take one look at Jupyter/your system and will point out "but one's fully open source and one's freemium," but nobody would be able to argue that, done right, freemium does undeniably have more resources going into it, and the developers involved get to work on something awesome AND go home to a full kitchen at the end of the day, which does sort of guarantee a certain consistent level of quality.)

In this model, you would have this hosted version with ALL THE PACKAGES (wow!) - and maybe some awesome paid features down the track - along with a slightly smaller-scale Github repo that people can clone and fire up locally.

Besides being "trendy", the downloadable version would be a boon for people who, for whatever reason, MUST have an air gap in their systems for whatever security purposes, but happen to be using Node for their work.

Finally, it'd be cool to offer the local version as both a loopback web server (for a standard browser) as well as an Electron[3]-based "standalone console". That puts you visually on par with IPython web notebooks and QtConsole.

Oh, and speaking of UI, one other thing would be to keep the downloadable version's UI as identical to the hosted version as possible, in both look and feel: it'd be a neat little mind trick to make devs feel like they're running your hosted version locally :P

[1]: https://developers.google.com/maps/documentation/javascript/...

[2]: http://netflix.github.io/falcor/

[3]: https://github.com/atom/electron

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!

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 :)

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

I really need to dig into this more! That's exactly what I was thinking! Fantastic!

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.

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.

Cmd + Enter should now work.

Also two space brackets are standard for Idiomatic JS and AibBnB Style Guide. jQuery uses four but that's because of age.

Isn't that mostly an artifact of deeply nested callbacks? With promises, generators, and what not I've been seeing a lot of new Javascript going back to 4. Is there a pragmatic reason for 2 going forward? I realize it's mostly trivial but I have a much easier time visually parsing 4 vs 2. I also sort've appreciate that it pressures me to reduce indentation.

Building text editors is such a minefield of personal opinions :)

Someday there will probably be preferences for all of this, but we wanted to focus on the core experience first and get something out there people could use.

I agree. I keep accidentally pressing Cmd + Enter.

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

Beautiful work! Reminds me of a very polished Jupyter.

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

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.

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.

This is amazing, good work!

Are you guys going to open source it or will this be a paid service?

Thanks so much

There's certainly a ton of stuff we'd love to open source, but we've been focused on getting it out the door. This product is also interesting in that the ops is as challenging as the code itself, so there may be some interesting opportunities to offer paid services later, if people start wanting to do more interesting things with it. We're really just kind of hoping people show us how they can use it.

I was impressed by the Time Travel.

If I delete a file through there, and "go back in time" would the files would still be there?

Yup. The time travel stuff is somewhat transparent and hard to talk about. If you think of the document as a .js file, than it is pretty easy to reason about what will happen. Things are just executed in order. The magic is that we don't have to re-execute a bunch of stuff every time just to get to your actual change.

> The time travel stuff is somewhat transparent and hard to talk about.

Wouldn't that mean it's opaque, since we can't see see into it?

PS. That's picky. This is a rad project and I love the time travel & the 'requiring packages automatically installing them' feature too.

Do you override 'require('fs')' or do you do some magic at the OS level ?

We use docker pretty extensively, and so between each code cell we can evaluate the layered filesystem docker provides for changes and save them.

Good, thanks.

This is awesome. Any plans to support other JS based languages (like Clojure via. planck)?

See the other answer in this thread :)

awesome work! would be a great tool in learning and teaching node :)

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

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

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.

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.

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.

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.

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.

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.

Oh great to hear! Awesome.

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

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.

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.

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.

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

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 ?

Looks like they are using this: https://github.com/facebook/regenerator

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.

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

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.

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

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.

Just a heads up your first issue should now be resolved.

would be cool if fat arrows work

also coffee script!

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.

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

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

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


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

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.

We also are having a few issues with versions that aren't semvered correctly (server.valid returns false). Its super helpful if you tell us which modules are returning that so we can quickly fix it and get a fast turnaround for you.

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

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.

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

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

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.

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.

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

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

Myself (and likely others) would be willing to pay for an offline version.

Super awesome. Well done guys!

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

Nope. That team is doing really interesting work.

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.


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.

Not sure what you're talking about. The design looks completely different and they do different things. Juno seems like a code editor with fancy features. This Tonic on the other hand is a repl.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact