diff --git a/example/package.json b/example/package.json
index 526095660f960ff8a04c1183163245b2cf8de90c..954cac47e2fa95e0c50583264ae8c34f2dd9af4b 100644
--- a/example/package.json
+++ b/example/package.json
@@ -11,8 +11,8 @@
     "gl-react-blur": "^1.2.2",
     "gl-react-native": "file:..",
     "glsl-transitions": "^2016.2.15",
-    "react": "^15.0.0",
-    "react-native": "^0.26.0",
+    "react": "^15.1.0",
+    "react-native": "^0.27.2",
     "react-native-fs": "^1.4.0",
     "react-native-material-kit": "PyYoshi/react-native-material-kit#rn-0.25.1",
     "react-transform-hmr": "^1.0.2",
diff --git a/example/src/Animated/index.js b/example/src/Animated/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..2c296739e94dc32895e6351f529bf95e9e410e47
--- /dev/null
+++ b/example/src/Animated/index.js
@@ -0,0 +1,47 @@
+import React, {Component} from "react";
+import {View, Animated } from "react-native";
+import {AnimatedSurface} from "gl-react-native";
+import GL from "gl-react";
+import Dimensions from "Dimensions";
+const { width: viewportW, height: viewportH } = Dimensions.get("window");
+
+export default class Tests extends Component {
+  state = {
+    heightValue: new Animated.Value(200)
+  };
+  componentWillMount () {
+    let i = 0;
+    this.interval = setInterval(() => {
+      Animated.spring(this.state.heightValue, {
+        toValue: ++i % 2 ? 500 : 200,
+      }).start();
+    }, 1000);
+  }
+  componentWillUnmount () {
+    clearInterval(this.interval);
+  }
+  render () {
+    const { heightValue } = this.state;
+    return 
+      
+        
+    
+    ;
+  }
+}
diff --git a/example/src/index.js b/example/src/index.js
index 56b99fa55bedd46fe256d56f0c2815bacaf95ec1..6395a1d01e14da4dde6e62fb66d6aaf1c754e6f8 100644
--- a/example/src/index.js
+++ b/example/src/index.js
@@ -1,12 +1,13 @@
 import React, {Component, PropTypes} from "react";
 import {StyleSheet, View, Text, TouchableOpacity, Navigator, AsyncStorage} from "react-native";
 
-const screens = {
-  Simple: require("./Simple"),
-  AdvancedEffects: require("./AdvancedEffects"),
-  Hearts: require("./Hearts"),
-  Tests: require("./Tests"),
-};
+import Simple from "./Simple";
+import AdvancedEffects from "./AdvancedEffects";
+import Hearts from "./Hearts";
+import Tests from "./Tests";
+import Animated from "./Animated";
+
+const screens = { Simple, AdvancedEffects, Hearts, Tests, Animated };
 
 const homeRoute = {
   id: "home",
@@ -18,6 +19,7 @@ const routes = [
   { id: "AdvancedEffects" },
   { id: "Hearts" },
   { id: "Tests" },
+  { id: "Animated" },
 ];
 
 const styles = StyleSheet.create({
diff --git a/src/GLCanvas.js b/src/GLCanvas.js
index 1297b9eb41cb49d90567b5d820acc59c596c2c2d..a174c0dac03ce4de2dbf0cb1810193e2fc56f865 100644
--- a/src/GLCanvas.js
+++ b/src/GLCanvas.js
@@ -104,6 +104,7 @@ class GLCanvas extends Component {
       width, height,
       onLoad, onProgress, eventsThrough,
       ...restProps } = this.props;
+
     return  props.scale || PixelRatio.get();
-
-function renderVcontent (width, height, id, children, { visibleContent }) {
-  const childrenStyle = {
-    position: "absolute",
-    top: visibleContent ? 0 : height, // as a workaround for RN, we offset the content so it is not visible but still can be rasterized
-    left: 0,
-    width: width,
-    height: height,
-    overflow: "hidden",
-  };
-  return {children};
-}
-
-function renderVGL (props) {
-  return ;
-}
-
-function renderVcontainer ({ style, width, height, visibleContent, eventsThrough }, contents, renderer) {
-  const parentStyle = [
-    {
-      position: "relative",
-    },
-    style,
-    {
-      width: width,
-      height: height,
-      overflow: "hidden",
-    }
-  ];
-  return 
-    {contents}
-    {renderer}
-  ;
-}
-
-module.exports = createSurface(
-  renderVcontainer,
-  renderVcontent,
-  renderVGL,
-  getPixelRatio);
diff --git a/src/index.js b/src/index.js
index 436871ffa22aecc7ea51672f126bcbcda0e69f85..61e73d57d1aac68709b1b05037b9c6bd724171fa 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,9 @@
 import invariant from "invariant";
 import { Shaders } from "gl-react";
-import Surface from "./Surface";
-import {NativeModules} from "react-native";
+import isAnimated from "gl-react/src/isAnimated";
+import makeSurface from "./makeSurface";
+import GLCanvas from "./GLCanvas";
+import {NativeModules, View, Animated} from "react-native";
 const {RNGLContext} = NativeModules;
 invariant(RNGLContext,
 `gl-react-native: the native module is not available.
@@ -22,5 +24,21 @@ Shaders.setImplementation({
 });
 
 module.exports = {
-  Surface
+  Surface: makeSurface({
+    View,
+    GLCanvas,
+    dimensionInvariant: (value, field) =>
+      isAnimated(value)
+      ? invariant(false, "GL.Surface "+field+" prop cannot be an Animated object. Use GL.AnimatedSurface instead")
+      : invariant(typeof value === "number" && value > 0, "GL.Surface: "+field+" prop must be a strictly positive number")
+  }),
+  AnimatedSurface: makeSurface({
+    View: Animated.View,
+    GLCanvas: Animated.createAnimatedComponent(GLCanvas),
+    dimensionInvariant: (value, field) =>
+      invariant(
+        isAnimated(value) || typeof value === "number" && value > 0,
+        "GL.AnimatedSurface: "+field+" must be a strictly positive number OR an Animated object"
+      )
+  }),
 };
diff --git a/src/makeSurface.js b/src/makeSurface.js
new file mode 100644
index 0000000000000000000000000000000000000000..429193d5baaaefd9a4acc32f0c1bc908749d66cd
--- /dev/null
+++ b/src/makeSurface.js
@@ -0,0 +1,54 @@
+import invariant from "invariant";
+import {createSurface} from "gl-react";
+import React from "react";
+import {PixelRatio} from "react-native";
+
+invariant(typeof createSurface === "function",
+"gl-react createSurface is not a function. Check your gl-react dependency");
+
+const getPixelRatio = props => props.scale || PixelRatio.get();
+
+export default C => {
+  const renderVcontainer = ({ style, width, height, visibleContent, eventsThrough }, contents, renderer) => {
+    const parentStyle = [
+      {
+        position: "relative",
+      },
+      style,
+      {
+        width: width,
+        height: height,
+        overflow: "hidden",
+      }
+    ];
+    return 
+      {contents}
+      {renderer}
+    ;
+  };
+  const renderVcontent = (width, height, id, children, { visibleContent }) => {
+    const childrenStyle = {
+      position: "absolute",
+      top: visibleContent ? 0 : height, // as a workaround for RN, we offset the content so it is not visible but still can be rasterized
+      left: 0,
+      width: width,
+      height: height,
+      overflow: "hidden",
+    };
+    return {children};
+  };
+  const renderVGL = props => {
+    C.dimensionInvariant(props.width, "width");
+    C.dimensionInvariant(props.height, "height");
+    return ;
+  };
+
+  return createSurface(
+    renderVcontainer,
+    renderVcontent,
+    renderVGL,
+    getPixelRatio,
+  );
+};