"7.5% time" project at Sulake using Go 2010: First (and only) contribution to Go 2011: IRC-Galleria uses Go in production 2011: Early Ninchat prototype in pure Go 2012: Ninchat uses Go among other languages 2014: Ninchat uses GopherJS
e m a i n i m p o r t " g i t h u b . c o m / g o p h e r j s / g o p h e r j s / j s " v a r d o c = j s . G l o b a l . G e t ( " d o c u m e n t " ) f u n c m a i n ( ) { d i v : = d o c . C a l l ( " c r e a t e E l e m e n t " , " d i v " ) d i v . S e t ( " i n n e r T e x t " , " h e l l o w o r l d " ) d o c . G e t ( " b o d y " ) . C a l l ( " a p p e n d C h i l d " , d i v ) }
n s t M y S t r i n g = " h e l l o w o r l d " f u n c M y A p p l y F u n c ( c a l l a b l e * j s . O b j e c t , a r g s t r i n g ) { i f c a l l a b l e ! = j s . U n d e f i n e d { c a l l a b l e . I n v o k e ( a r g ) } } f u n c m a i n ( ) { j s . G l o b a l . G e t ( " w i n d o w " ) . S e t ( " M y S t u f f " , m a p [ s t r i n g ] i n t e r f a c e { } { " M Y _ S T R I N G " : M y S t r i n g , " m y A p p l y F u n c " : M y A p p l y F u n c , } ) } > M y S t u f f . m y A p p l y F u n c ( s o m e U n a r y F u n c t i o n , " a s d f " )
p e V a l u e T h i n g s t r u c t { F o o i n t B a r s t r i n g B a z [ ] u i n t 1 6 } f u n c N e w V a l u e T h i n g ( ) * V a l u e T h i n g { r e t u r n & V a l u e T h i n g { } } f u n c ( t * V a l u e T h i n g ) G e t S o m e t h i n g ( ) i n t { r e t u r n 4 2 } > t = e x a m p l e s . N e w V a l u e T h i n g ( ) > t O b j e c t { F o o : 0 , B a r : " " , B a z : A r r a y [ 0 ] } > t . G e t S o m e t h i n g ( ) Uncaught TypeError: t.GetSomething is not a function
p e A c t i v e T h i n g s t r u c t { F o o i n t B a r s t r i n g B a z [ ] u i n t 1 6 } f u n c N e w A c t i v e T h i n g ( ) * j s . O b j e c t { r e t u r n j s . M a k e W r a p p e r ( & A c t i v e T h i n g { } ) } f u n c ( t * A c t i v e T h i n g ) G e t S o m e t h i n g ( ) i n t { r e t u r n 4 2 } > t = e x a m p l e s . N e w A c t i v e T h i n g ( ) > t O b j e c t { i n t e r n a l s t u f f o n l y } > t . G e t S o m e t h i n g ( ) 4 2
" n e t / h t t p " f u n c M y E x p o r t e d F u n c 1 ( u r l s t r i n g ) { r , _ : = h t t p . G e t ( u r l ) / / b l o c k i n g c a l l p r i n t l n ( r ) } Works: i m p o r t " n e t / h t t p " f u n c M y E x p o r t e d F u n c 2 ( u r l s t r i n g ) { g o f u n c ( ) { r , _ : = h t t p . G e t ( u r l ) / / b l o c k i n g c a l l p r i n t l n ( r ) } ( ) }
j s . g o / / + b u i l d j s i m p o r t " g i t h u b . c o m / g o p h e r j s / g o p h e r j s / j s " f u n c D i s p l a y ( m e s s a g e s t r i n g ) { j s . G l o b a l . G e t ( " c o n s o l e " ) . C a l l ( " l o g " , m e s s a g e ) } m y c o d e _ d e f a u l t . g o / / + b u i l d ! j s i m p o r t " f m t " i m p o r t " o s " f u n c D i s p l a y ( m e s s a g e s t r i n g ) { f m t . F p r i n t l n ( o s . S t d e r r , m e s s a g e ) }
machine thanks to goroutines Avoid bloat by using the browser's APIs directly Supports IE8+ with shims (and stubs for typed array types) Same code base supports also native Go h t t p s : / / g i t h u b . c o m / n i n c h a t / n i n c h a t - g o is an importable Go package h t t p s : / / g i t h u b . c o m / n i n c h a t / n i n c h a t - j s is the main package
code 13% native Go wrapper code (for custom abstractions) File size: 157 KB mini ed 30 KB mini ed and gzipped Estimated le size without direct browser API calls: 3 MB mini ed 600 KB mini ed and gzipped
worlds takes time UI framework etc. take up most of the time anyway Internet says: "Performance is quite good in most cases" Microbenchmarks may be 1000x slower than native Go ...or they may be faster, thanks to V8
package (etc.) if le size matters Mapping complicated Go APIs to JavaScript is complicated As for running Go code in the browser: it just works! Goroutines, channels and static typing bring their bene ts if a reasonably self- contained part of your application is implemented in Go