diff --git a/docs/components/ProgressBar.md b/docs/components/ProgressBar.md
new file mode 100644
index 00000000..80064773
--- /dev/null
+++ b/docs/components/ProgressBar.md
@@ -0,0 +1,23 @@
+# ProgressBar
+
+Display an activity progress bar.
+
+## Props
+
+[...View props](./View.md)
+
+**color**: string = '#1976D2'
+
+Color of the progress bar.
+
+**indeterminate**: bool = true
+
+Whether the progress bar will show indeterminate progress.
+
+**progress**: number
+
+The progress value (between 0 and 1).
+
+(web) **trackColor**: string = 'transparent'
+
+Color of the track bar.
diff --git a/examples/components/ProgressBar/ProgressBarExample.js b/examples/components/ProgressBar/ProgressBarExample.js
new file mode 100644
index 00000000..8046b978
--- /dev/null
+++ b/examples/components/ProgressBar/ProgressBarExample.js
@@ -0,0 +1,96 @@
+import { ProgressBar, StyleSheet, View } from 'react-native'
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import TimerMixin from 'react-timer-mixin';
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * The examples provided by Facebook are for non-commercial testing and
+ * evaluation purposes only.
+ *
+ * Facebook reserves all rights not expressly granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
+ * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @flow
+ */
+
+var ProgressBarExample = React.createClass({
+ mixins: [TimerMixin],
+
+ getInitialState() {
+ return {
+ progress: 0,
+ };
+ },
+
+ componentDidMount() {
+ this.updateProgress();
+ },
+
+ updateProgress() {
+ var progress = this.state.progress + 0.01;
+ this.setState({ progress });
+ this.requestAnimationFrame(() => this.updateProgress());
+ },
+
+ getProgress(offset) {
+ var progress = this.state.progress + offset;
+ return Math.sin(progress % Math.PI) % 1;
+ },
+
+ render() {
+ return (
+
+
+
+
+
+
+ );
+ },
+});
+
+const examples = [{
+ title: 'progress',
+ render() {
+ return (
+
+ );
+ },
+}, {
+ title: 'indeterminate',
+ render() {
+ return (
+
+ );
+ }
+}];
+
+var styles = StyleSheet.create({
+ container: {
+ minWidth: 200,
+ marginTop: -20,
+ backgroundColor: 'transparent',
+ },
+ progressView: {
+ marginTop: 20,
+ minWidth: 200
+ }
+});
+
+examples.forEach((example) => {
+ storiesOf('component: ProgressBar', module)
+ .add(example.title, () => example.render())
+})
diff --git a/src/components/ProgressBar/__tests__/index-test.js b/src/components/ProgressBar/__tests__/index-test.js
new file mode 100644
index 00000000..1df0bf09
--- /dev/null
+++ b/src/components/ProgressBar/__tests__/index-test.js
@@ -0,0 +1,20 @@
+/* eslint-env mocha */
+
+import assert from 'assert';
+import React from 'react';
+import { shallow } from 'enzyme';
+import ProgressBar from '..';
+
+suite('components/ProgressBar', () => {
+ suite('progress', () => {
+ test('value as percentage is set to "aria-valuenow"', () => {
+ const component = shallow();
+ assert(component.prop('aria-valuenow') === 50);
+ });
+
+ test('is ignored when "indeterminate" is "true"', () => {
+ const component = shallow();
+ assert(component.prop('aria-valuenow') === null);
+ });
+ });
+});
diff --git a/src/components/ProgressBar/index.js b/src/components/ProgressBar/index.js
new file mode 100644
index 00000000..3a5c81e2
--- /dev/null
+++ b/src/components/ProgressBar/index.js
@@ -0,0 +1,119 @@
+import Animated from '../../apis/Animated';
+import applyNativeMethods from '../../modules/applyNativeMethods';
+import ColorPropType from '../../propTypes/ColorPropType';
+import StyleSheet from '../../apis/StyleSheet';
+import View from '../View';
+import React, { Component, PropTypes } from 'react';
+
+const indeterminateWidth = '25%';
+const translateInterpolation = { inputRange: [ 0, 1 ], outputRange: [ '-100%', '400%' ] };
+
+class ProgressBar extends Component {
+ static propTypes = {
+ ...View.propTypes,
+ color: ColorPropType,
+ indeterminate: PropTypes.bool,
+ progress: PropTypes.number,
+ trackColor: ColorPropType
+ };
+
+ static defaultProps = {
+ color: '#1976D2',
+ indeterminate: false,
+ progress: 0,
+ trackColor: 'transparent'
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ animationScale: new Animated.Value(0),
+ animationTranslate: new Animated.Value(0)
+ };
+ }
+
+ componentDidMount() {
+ this._manageAnimation();
+ }
+
+ componentDidUpdate() {
+ this._manageAnimation();
+ }
+
+ render() {
+ const {
+ color,
+ indeterminate,
+ progress,
+ trackColor,
+ style,
+ ...other
+ } = this.props;
+
+ const { animationTranslate } = this.state;
+
+ const percentageProgress = indeterminate ? 50 : progress * 100;
+
+ return (
+
+
+
+ );
+ }
+
+ _manageAnimation() {
+ const { animationTranslate } = this.state;
+
+ const cycleAnimation = (animation) => {
+ animation.setValue(0);
+ Animated.timing(animation, {
+ duration: 1000,
+ toValue: 1
+ }).start((event) => {
+ if (event.finished) {
+ cycleAnimation(animation);
+ }
+ });
+ };
+
+ if (this.props.indeterminate) {
+ cycleAnimation(animationTranslate);
+ } else {
+ animationTranslate.stopAnimation();
+ }
+ }
+}
+
+const styles = StyleSheet.create({
+ track: {
+ height: 5,
+ overflow: 'hidden',
+ userSelect: 'none'
+ },
+ progress: {
+ height: '100%'
+ }
+});
+
+module.exports = applyNativeMethods(ProgressBar);
diff --git a/src/index.js b/src/index.js
index 21f6c71b..bb7e2102 100644
--- a/src/index.js
+++ b/src/index.js
@@ -25,6 +25,7 @@ import Vibration from './apis/Vibration';
import ActivityIndicator from './components/ActivityIndicator';
import Image from './components/Image';
import ListView from './components/ListView';
+import ProgressBar from './components/ProgressBar';
import ScrollView from './components/ScrollView';
import Switch from './components/Switch';
import Text from './components/Text';
@@ -75,6 +76,7 @@ const ReactNative = {
ActivityIndicator,
Image,
ListView,
+ ProgressBar,
ScrollView,
Switch,
Text,